From 7988d3084d54ebafffad6a27d4b19688fd5b9685 Mon Sep 17 00:00:00 2001 From: Ariel Mashraki <7413593+a8m@users.noreply.github.com> Date: Mon, 16 Mar 2020 00:19:27 +0200 Subject: [PATCH] entc/hooks: initial work for mutations and hooks (#377) * entc/hooks: initial work for mutations and hooks * ent/schema: adding policy to schema * ent: change op string to uint * entc: move entschema to runtime and enable smooth transition * entc/privacy: adding privacy template * all: goimports * intg/hooks: mutation client/tx and basic schema tests * ent/privacy: adding more verbose decisions * entc/gen: edge-ids getter and additional tests * all: regen assets * entc/gen: fix client hookd propagation * intg: add deletion example * intg/privacy: remove old entschema package * typed privacy * ent/privacy: hooks shouldn't be called on privacy deny * entc/gen: fix schema hooks invocation order * remove read policy from public api * update circleci go orb Co-authored-by: Ariel Mashraki --- .circleci/config.yml | 6 +- .../gremlin/encoding/graphson/bench_test.go | 2 +- .../gremlin/encoding/graphson/common_test.go | 2 +- dialect/gremlin/encoding/graphson/decode.go | 2 +- dialect/gremlin/encoding/graphson/encode.go | 2 +- dialect/gremlin/encoding/graphson/error.go | 2 +- .../gremlin/encoding/graphson/extension.go | 2 +- dialect/gremlin/encoding/graphson/init.go | 2 +- .../gremlin/encoding/graphson/interface.go | 2 +- dialect/gremlin/encoding/graphson/lazy.go | 2 +- .../gremlin/encoding/graphson/lazy_test.go | 2 +- dialect/gremlin/encoding/graphson/map.go | 2 +- dialect/gremlin/encoding/graphson/map_test.go | 2 +- .../gremlin/encoding/graphson/marshaler.go | 2 +- .../encoding/graphson/marshaler_test.go | 2 +- dialect/gremlin/encoding/graphson/native.go | 2 +- .../gremlin/encoding/graphson/native_test.go | 2 +- dialect/gremlin/encoding/graphson/slice.go | 2 +- dialect/gremlin/encoding/graphson/struct.go | 4 +- dialect/gremlin/encoding/graphson/time.go | 2 +- dialect/gremlin/encoding/graphson/type.go | 2 +- dialect/gremlin/encoding/graphson/util.go | 2 +- .../gremlin/encoding/graphson/util_test.go | 2 +- dialect/gremlin/expand.go | 2 +- ent.go | 174 + entc/entc.go | 15 +- entc/gen/func.go | 20 + entc/gen/graph.go | 50 +- entc/gen/internal/bindata.go | 178 +- entc/gen/template.go | 22 +- entc/gen/template/base.tmpl | 10 + entc/gen/template/builder/create.tmpl | 92 +- entc/gen/template/builder/delete.tmpl | 36 +- entc/gen/template/builder/mutation.tmpl | 587 ++ entc/gen/template/builder/query.tmpl | 7 + entc/gen/template/builder/setter.tmpl | 24 +- entc/gen/template/builder/update.tmpl | 111 +- entc/gen/template/client.tmpl | 90 +- entc/gen/template/config.tmpl | 9 + entc/gen/template/dialect/gremlin/create.tmpl | 15 +- entc/gen/template/dialect/gremlin/meta.tmpl | 4 +- .../template/dialect/gremlin/predicate.tmpl | 8 +- entc/gen/template/dialect/gremlin/query.tmpl | 12 +- entc/gen/template/dialect/gremlin/update.tmpl | 39 +- entc/gen/template/dialect/sql/create.tmpl | 15 +- entc/gen/template/dialect/sql/update.tmpl | 30 +- entc/gen/template/hook.tmpl | 66 + entc/gen/template/import.tmpl | 4 - entc/gen/template/meta.tmpl | 104 +- entc/gen/template/migrate/schema.tmpl | 2 +- entc/gen/template/privacy.tmpl | 169 + entc/gen/template/runtime.tmpl | 169 + entc/gen/template/tx.tmpl | 18 +- entc/gen/type.go | 104 +- entc/gen/type_test.go | 6 +- entc/integration/config/ent/client.go | 64 +- entc/integration/config/ent/config.go | 8 + entc/integration/config/ent/ent.go | 11 + entc/integration/config/ent/hook/hook.go | 61 + entc/integration/config/ent/mutation.go | 220 + .../integration/config/ent/privacy/privacy.go | 171 + entc/integration/config/ent/runtime.go | 13 + .../integration/config/ent/runtime/runtime.go | 13 + entc/integration/config/ent/tx.go | 13 +- entc/integration/config/ent/user_create.go | 28 +- entc/integration/config/ent/user_delete.go | 28 +- entc/integration/config/ent/user_update.go | 62 +- entc/integration/customid/customid_test.go | 1 - entc/integration/customid/ent/blob/blob.go | 15 +- entc/integration/customid/ent/blob_create.go | 74 +- entc/integration/customid/ent/blob_delete.go | 28 +- entc/integration/customid/ent/blob_update.go | 161 +- entc/integration/customid/ent/car/car.go | 6 +- entc/integration/customid/ent/car_create.go | 50 +- entc/integration/customid/ent/car_delete.go | 28 +- entc/integration/customid/ent/car_update.go | 113 +- entc/integration/customid/ent/client.go | 196 +- entc/integration/customid/ent/config.go | 12 + entc/integration/customid/ent/ent.go | 11 + entc/integration/customid/ent/group/group.go | 3 + entc/integration/customid/ent/group_create.go | 49 +- entc/integration/customid/ent/group_delete.go | 28 +- entc/integration/customid/ent/group_update.go | 114 +- entc/integration/customid/ent/hook/hook.go | 113 + .../customid/ent/migrate/schema.go | 4 +- entc/integration/customid/ent/mutation.go | 1740 ++++ entc/integration/customid/ent/pet/pet.go | 5 + entc/integration/customid/ent/pet_create.go | 61 +- entc/integration/customid/ent/pet_delete.go | 28 +- entc/integration/customid/ent/pet_update.go | 147 +- .../customid/ent/privacy/privacy.go | 267 + entc/integration/customid/ent/runtime.go | 24 + .../customid/ent/runtime/runtime.go | 13 + entc/integration/customid/ent/tx.go | 21 +- entc/integration/customid/ent/user/user.go | 9 + entc/integration/customid/ent/user_create.go | 85 +- entc/integration/customid/ent/user_delete.go | 28 +- entc/integration/customid/ent/user_update.go | 243 +- entc/integration/ent/card/card.go | 49 +- entc/integration/ent/card_create.go | 106 +- entc/integration/ent/card_delete.go | 28 +- entc/integration/ent/card_update.go | 203 +- entc/integration/ent/client.go | 427 +- entc/integration/ent/comment/comment.go | 9 +- entc/integration/ent/comment_create.go | 59 +- entc/integration/ent/comment_delete.go | 28 +- entc/integration/ent/comment_update.go | 196 +- entc/integration/ent/config.go | 19 + entc/integration/ent/ent.go | 11 + entc/integration/ent/fieldtype/fieldtype.go | 82 +- entc/integration/ent/fieldtype_create.go | 261 +- entc/integration/ent/fieldtype_delete.go | 28 +- entc/integration/ent/fieldtype_update.go | 1241 +-- entc/integration/ent/file/file.go | 29 +- entc/integration/ent/file_create.go | 99 +- entc/integration/ent/file_delete.go | 28 +- entc/integration/ent/file_update.go | 248 +- entc/integration/ent/filetype/filetype.go | 6 +- entc/integration/ent/filetype_create.go | 51 +- entc/integration/ent/filetype_delete.go | 28 +- entc/integration/ent/filetype_update.go | 128 +- entc/integration/ent/group/group.go | 81 +- entc/integration/ent/group_create.go | 151 +- entc/integration/ent/group_delete.go | 28 +- entc/integration/ent/group_update.go | 393 +- entc/integration/ent/groupinfo/groupinfo.go | 19 +- entc/integration/ent/groupinfo_create.go | 64 +- entc/integration/ent/groupinfo_delete.go | 28 +- entc/integration/ent/groupinfo_update.go | 168 +- entc/integration/ent/hook/hook.go | 204 + entc/integration/ent/item_create.go | 28 +- entc/integration/ent/item_delete.go | 28 +- entc/integration/ent/item_update.go | 62 +- entc/integration/ent/migrate/schema.go | 17 +- entc/integration/ent/mutation.go | 7539 +++++++++++++++++ entc/integration/ent/node/node.go | 8 +- entc/integration/ent/node_create.go | 62 +- entc/integration/ent/node_delete.go | 28 +- entc/integration/ent/node_update.go | 187 +- entc/integration/ent/pet/pet.go | 8 +- entc/integration/ent/pet_create.go | 63 +- entc/integration/ent/pet_delete.go | 28 +- entc/integration/ent/pet_update.go | 149 +- entc/integration/ent/privacy/privacy.go | 435 + entc/integration/ent/runtime.go | 131 + entc/integration/ent/runtime/runtime.go | 13 + entc/integration/ent/spec/spec.go | 3 + entc/integration/ent/spec_create.go | 40 +- entc/integration/ent/spec_delete.go | 28 +- entc/integration/ent/spec_update.go | 114 +- entc/integration/ent/tx.go | 35 +- entc/integration/ent/user/user.go | 67 +- entc/integration/ent/user_create.go | 255 +- entc/integration/ent/user_delete.go | 28 +- entc/integration/ent/user_update.go | 770 +- entc/integration/gremlin/ent/card/card.go | 49 +- entc/integration/gremlin/ent/card_create.go | 94 +- entc/integration/gremlin/ent/card_delete.go | 28 +- entc/integration/gremlin/ent/card_update.go | 191 +- entc/integration/gremlin/ent/client.go | 424 +- .../gremlin/ent/comment/comment.go | 9 +- .../integration/gremlin/ent/comment_create.go | 61 +- .../integration/gremlin/ent/comment_delete.go | 28 +- .../integration/gremlin/ent/comment_update.go | 227 +- entc/integration/gremlin/ent/config.go | 19 + entc/integration/gremlin/ent/ent.go | 11 + .../gremlin/ent/fieldtype/fieldtype.go | 82 +- .../gremlin/ent/fieldtype_create.go | 213 +- .../gremlin/ent/fieldtype_delete.go | 28 +- .../gremlin/ent/fieldtype_update.go | 1241 +-- entc/integration/gremlin/ent/file/file.go | 29 +- entc/integration/gremlin/ent/file_create.go | 87 +- entc/integration/gremlin/ent/file_delete.go | 28 +- entc/integration/gremlin/ent/file_update.go | 240 +- .../gremlin/ent/filetype/filetype.go | 6 +- .../gremlin/ent/filetype_create.go | 51 +- .../gremlin/ent/filetype_delete.go | 28 +- .../gremlin/ent/filetype_update.go | 128 +- entc/integration/gremlin/ent/group/group.go | 81 +- entc/integration/gremlin/ent/group_create.go | 133 +- entc/integration/gremlin/ent/group_delete.go | 28 +- entc/integration/gremlin/ent/group_update.go | 365 +- .../gremlin/ent/groupinfo/groupinfo.go | 19 +- .../gremlin/ent/groupinfo_create.go | 58 +- .../gremlin/ent/groupinfo_delete.go | 28 +- .../gremlin/ent/groupinfo_update.go | 160 +- entc/integration/gremlin/ent/hook/hook.go | 204 + entc/integration/gremlin/ent/item_create.go | 28 +- entc/integration/gremlin/ent/item_delete.go | 28 +- entc/integration/gremlin/ent/item_update.go | 62 +- entc/integration/gremlin/ent/mutation.go | 7539 +++++++++++++++++ entc/integration/gremlin/ent/node/node.go | 8 +- entc/integration/gremlin/ent/node_create.go | 56 +- entc/integration/gremlin/ent/node_delete.go | 28 +- entc/integration/gremlin/ent/node_update.go | 179 +- entc/integration/gremlin/ent/pet/pet.go | 8 +- entc/integration/gremlin/ent/pet_create.go | 57 +- entc/integration/gremlin/ent/pet_delete.go | 28 +- entc/integration/gremlin/ent/pet_update.go | 141 +- .../gremlin/ent/privacy/privacy.go | 435 + entc/integration/gremlin/ent/runtime.go | 131 + .../gremlin/ent/runtime/runtime.go | 13 + entc/integration/gremlin/ent/spec/spec.go | 3 + entc/integration/gremlin/ent/spec_create.go | 38 +- entc/integration/gremlin/ent/spec_delete.go | 28 +- entc/integration/gremlin/ent/spec_update.go | 106 +- entc/integration/gremlin/ent/tx.go | 33 +- entc/integration/gremlin/ent/user/user.go | 67 +- entc/integration/gremlin/ent/user_create.go | 225 +- entc/integration/gremlin/ent/user_delete.go | 28 +- entc/integration/gremlin/ent/user_update.go | 714 +- entc/integration/hooks/ent/card.go | 160 + entc/integration/hooks/ent/card/card.go | 65 + entc/integration/hooks/ent/card/where.go | 491 ++ entc/integration/hooks/ent/card_create.go | 201 + entc/integration/hooks/ent/card_delete.go | 112 + entc/integration/hooks/ent/card_query.go | 685 ++ entc/integration/hooks/ent/card_update.go | 430 + entc/integration/hooks/ent/client.go | 333 + entc/integration/hooks/ent/config.go | 64 + entc/integration/hooks/ent/context.go | 24 + entc/integration/hooks/ent/ent.go | 265 + entc/integration/hooks/ent/generate.go | 7 + entc/integration/hooks/ent/hook/hook.go | 74 + entc/integration/hooks/ent/migrate/migrate.go | 74 + entc/integration/hooks/ent/migrate/schema.go | 99 + entc/integration/hooks/ent/mutation.go | 832 ++ .../hooks/ent/predicate/predicate.go | 17 + entc/integration/hooks/ent/privacy/privacy.go | 195 + entc/integration/hooks/ent/runtime.go | 9 + entc/integration/hooks/ent/runtime/runtime.go | 39 + entc/integration/hooks/ent/schema/card.go | 76 + entc/integration/hooks/ent/schema/user.go | 29 + entc/integration/hooks/ent/tx.go | 101 + entc/integration/hooks/ent/user.go | 170 + entc/integration/hooks/ent/user/user.go | 55 + entc/integration/hooks/ent/user/where.go | 330 + entc/integration/hooks/ent/user_create.go | 207 + entc/integration/hooks/ent/user_delete.go | 112 + entc/integration/hooks/ent/user_query.go | 827 ++ entc/integration/hooks/ent/user_update.go | 619 ++ entc/integration/hooks/hooks_test.go | 134 + entc/integration/hooks/main.go | 69 + entc/integration/idtype/ent/client.go | 64 +- entc/integration/idtype/ent/config.go | 8 + entc/integration/idtype/ent/ent.go | 11 + entc/integration/idtype/ent/hook/hook.go | 61 + entc/integration/idtype/ent/mutation.go | 447 + .../integration/idtype/ent/privacy/privacy.go | 171 + entc/integration/idtype/ent/runtime.go | 13 + .../integration/idtype/ent/runtime/runtime.go | 13 + entc/integration/idtype/ent/tx.go | 13 +- entc/integration/idtype/ent/user/user.go | 10 +- entc/integration/idtype/ent/user_create.go | 74 +- entc/integration/idtype/ent/user_delete.go | 28 +- entc/integration/idtype/ent/user_update.go | 209 +- entc/integration/json/ent/client.go | 64 +- entc/integration/json/ent/config.go | 8 + entc/integration/json/ent/ent.go | 11 + entc/integration/json/ent/hook/hook.go | 61 + entc/integration/json/ent/mutation.go | 545 ++ entc/integration/json/ent/privacy/privacy.go | 171 + entc/integration/json/ent/runtime.go | 13 + entc/integration/json/ent/runtime/runtime.go | 13 + entc/integration/json/ent/tx.go | 13 +- entc/integration/json/ent/user/user.go | 18 +- entc/integration/json/ent/user_create.go | 82 +- entc/integration/json/ent/user_delete.go | 28 +- entc/integration/json/ent/user_update.go | 220 +- entc/integration/migrate/entv1/car/car.go | 3 + entc/integration/migrate/entv1/car_create.go | 40 +- entc/integration/migrate/entv1/car_delete.go | 28 +- entc/integration/migrate/entv1/car_update.go | 99 +- entc/integration/migrate/entv1/client.go | 97 +- entc/integration/migrate/entv1/config.go | 9 + entc/integration/migrate/entv1/ent.go | 11 + entc/integration/migrate/entv1/hook/hook.go | 74 + entc/integration/migrate/entv1/mutation.go | 1085 +++ .../migrate/entv1/privacy/privacy.go | 195 + entc/integration/migrate/entv1/runtime.go | 24 + .../migrate/entv1/runtime/runtime.go | 13 + entc/integration/migrate/entv1/tx.go | 15 +- entc/integration/migrate/entv1/user/user.go | 40 +- entc/integration/migrate/entv1/user_create.go | 164 +- entc/integration/migrate/entv1/user_delete.go | 28 +- entc/integration/migrate/entv1/user_update.go | 406 +- entc/integration/migrate/entv2/car/car.go | 3 + entc/integration/migrate/entv2/car_create.go | 40 +- entc/integration/migrate/entv2/car_delete.go | 28 +- entc/integration/migrate/entv2/car_update.go | 99 +- entc/integration/migrate/entv2/client.go | 163 +- entc/integration/migrate/entv2/config.go | 11 + entc/integration/migrate/entv2/ent.go | 11 + .../integration/migrate/entv2/group_create.go | 28 +- .../integration/migrate/entv2/group_delete.go | 28 +- .../integration/migrate/entv2/group_update.go | 62 +- entc/integration/migrate/entv2/hook/hook.go | 100 + .../migrate/entv2/migrate/schema.go | 6 +- entc/integration/migrate/entv2/mutation.go | 1429 ++++ entc/integration/migrate/entv2/pet_create.go | 28 +- entc/integration/migrate/entv2/pet_delete.go | 28 +- entc/integration/migrate/entv2/pet_update.go | 62 +- .../migrate/entv2/privacy/privacy.go | 243 + entc/integration/migrate/entv2/runtime.go | 28 + .../migrate/entv2/runtime/runtime.go | 13 + entc/integration/migrate/entv2/tx.go | 19 +- entc/integration/migrate/entv2/user/user.go | 47 +- entc/integration/migrate/entv2/user_create.go | 158 +- entc/integration/migrate/entv2/user_delete.go | 28 +- entc/integration/migrate/entv2/user_update.go | 354 +- entc/integration/privacy/ent/client.go | 202 + entc/integration/privacy/ent/config.go | 63 + entc/integration/privacy/ent/context.go | 24 + entc/integration/privacy/ent/ent.go | 265 + entc/integration/privacy/ent/generate.go | 7 + entc/integration/privacy/ent/hook/hook.go | 61 + .../privacy/ent/migrate/migrate.go | 74 + .../integration/privacy/ent/migrate/schema.go | 65 + entc/integration/privacy/ent/mutation.go | 416 + entc/integration/privacy/ent/planet.go | 126 + entc/integration/privacy/ent/planet/planet.go | 53 + entc/integration/privacy/ent/planet/where.go | 371 + entc/integration/privacy/ent/planet_create.go | 161 + entc/integration/privacy/ent/planet_delete.go | 112 + entc/integration/privacy/ent/planet_query.go | 712 ++ entc/integration/privacy/ent/planet_update.go | 430 + .../privacy/ent/predicate/predicate.go | 14 + .../privacy/ent/privacy/privacy.go | 171 + entc/integration/privacy/ent/runtime.go | 9 + .../privacy/ent/runtime/runtime.go | 43 + entc/integration/privacy/ent/schema/planet.go | 50 + entc/integration/privacy/ent/tx.go | 98 + entc/integration/privacy/privacy_test.go | 41 + entc/integration/privacy/rule/rule.go | 68 + entc/integration/template/ent/client.go | 130 +- entc/integration/template/ent/config.go | 10 + entc/integration/template/ent/ent.go | 11 + entc/integration/template/ent/group/group.go | 3 +- entc/integration/template/ent/group_create.go | 39 +- entc/integration/template/ent/group_delete.go | 28 +- entc/integration/template/ent/group_update.go | 104 +- entc/integration/template/ent/hook/hook.go | 87 + entc/integration/template/ent/mutation.go | 1042 +++ entc/integration/template/ent/pet/pet.go | 9 +- entc/integration/template/ent/pet_create.go | 59 +- entc/integration/template/ent/pet_delete.go | 28 +- entc/integration/template/ent/pet_update.go | 165 +- .../template/ent/privacy/privacy.go | 219 + entc/integration/template/ent/runtime.go | 13 + .../template/ent/runtime/runtime.go | 13 + entc/integration/template/ent/tx.go | 17 +- entc/integration/template/ent/user/user.go | 8 +- entc/integration/template/ent/user_create.go | 63 +- entc/integration/template/ent/user_delete.go | 28 +- entc/integration/template/ent/user_update.go | 176 +- entc/load/internal/bindata.go | 8 +- entc/load/load.go | 24 +- entc/load/schema.go | 97 +- entc/load/template/main.tmpl | 2 +- examples/edgeindex/ent/city/city.go | 6 +- examples/edgeindex/ent/city_create.go | 51 +- examples/edgeindex/ent/city_delete.go | 28 +- examples/edgeindex/ent/city_update.go | 128 +- examples/edgeindex/ent/client.go | 97 +- examples/edgeindex/ent/config.go | 9 + examples/edgeindex/ent/ent.go | 11 + examples/edgeindex/ent/hook/hook.go | 74 + examples/edgeindex/ent/mutation.go | 616 ++ examples/edgeindex/ent/privacy/privacy.go | 195 + examples/edgeindex/ent/runtime.go | 13 + examples/edgeindex/ent/runtime/runtime.go | 13 + examples/edgeindex/ent/street/street.go | 6 +- examples/edgeindex/ent/street_create.go | 50 +- examples/edgeindex/ent/street_delete.go | 28 +- examples/edgeindex/ent/street_update.go | 113 +- examples/edgeindex/ent/tx.go | 15 +- examples/entcpkg/ent/client.go | 64 +- examples/entcpkg/ent/config.go | 8 + examples/entcpkg/ent/ent.go | 11 + examples/entcpkg/ent/hook/hook.go | 61 + examples/entcpkg/ent/mutation.go | 220 + examples/entcpkg/ent/privacy/privacy.go | 171 + examples/entcpkg/ent/runtime.go | 13 + examples/entcpkg/ent/runtime/runtime.go | 13 + examples/entcpkg/ent/tx.go | 13 +- examples/entcpkg/ent/user_create.go | 28 +- examples/entcpkg/ent/user_delete.go | 28 +- examples/entcpkg/ent/user_update.go | 62 +- examples/m2m2types/ent/client.go | 97 +- examples/m2m2types/ent/config.go | 9 + examples/m2m2types/ent/ent.go | 11 + examples/m2m2types/ent/group/group.go | 6 +- examples/m2m2types/ent/group_create.go | 51 +- examples/m2m2types/ent/group_delete.go | 28 +- examples/m2m2types/ent/group_update.go | 128 +- examples/m2m2types/ent/hook/hook.go | 74 + examples/m2m2types/ent/mutation.go | 693 ++ examples/m2m2types/ent/privacy/privacy.go | 195 + examples/m2m2types/ent/runtime.go | 13 + examples/m2m2types/ent/runtime/runtime.go | 13 + examples/m2m2types/ent/tx.go | 15 +- examples/m2m2types/ent/user/user.go | 9 +- examples/m2m2types/ent/user_create.go | 62 +- examples/m2m2types/ent/user_delete.go | 28 +- examples/m2m2types/ent/user_update.go | 168 +- examples/m2mbidi/ent/client.go | 64 +- examples/m2mbidi/ent/config.go | 8 + examples/m2mbidi/ent/ent.go | 11 + examples/m2mbidi/ent/hook/hook.go | 61 + examples/m2mbidi/ent/mutation.go | 394 + examples/m2mbidi/ent/privacy/privacy.go | 171 + examples/m2mbidi/ent/runtime.go | 13 + examples/m2mbidi/ent/runtime/runtime.go | 13 + examples/m2mbidi/ent/tx.go | 13 +- examples/m2mbidi/ent/user/user.go | 9 +- examples/m2mbidi/ent/user_create.go | 62 +- examples/m2mbidi/ent/user_delete.go | 28 +- examples/m2mbidi/ent/user_update.go | 168 +- examples/m2mrecur/ent/client.go | 64 +- examples/m2mrecur/ent/config.go | 8 + examples/m2mrecur/ent/ent.go | 11 + examples/m2mrecur/ent/hook/hook.go | 61 + examples/m2mrecur/ent/mutation.go | 459 + examples/m2mrecur/ent/privacy/privacy.go | 171 + examples/m2mrecur/ent/runtime.go | 13 + examples/m2mrecur/ent/runtime/runtime.go | 13 + examples/m2mrecur/ent/tx.go | 13 +- examples/m2mrecur/ent/user/user.go | 11 +- examples/m2mrecur/ent/user_create.go | 74 +- examples/m2mrecur/ent/user_delete.go | 28 +- examples/m2mrecur/ent/user_update.go | 216 +- examples/o2m2types/ent/client.go | 97 +- examples/o2m2types/ent/config.go | 9 + examples/o2m2types/ent/ent.go | 11 + examples/o2m2types/ent/hook/hook.go | 74 + examples/o2m2types/ent/mutation.go | 687 ++ examples/o2m2types/ent/pet/pet.go | 6 +- examples/o2m2types/ent/pet_create.go | 50 +- examples/o2m2types/ent/pet_delete.go | 28 +- examples/o2m2types/ent/pet_update.go | 113 +- examples/o2m2types/ent/privacy/privacy.go | 195 + examples/o2m2types/ent/runtime.go | 13 + examples/o2m2types/ent/runtime/runtime.go | 13 + examples/o2m2types/ent/tx.go | 15 +- examples/o2m2types/ent/user/user.go | 9 +- examples/o2m2types/ent/user_create.go | 62 +- examples/o2m2types/ent/user_delete.go | 28 +- examples/o2m2types/ent/user_update.go | 168 +- examples/o2mrecur/ent/client.go | 64 +- examples/o2mrecur/ent/config.go | 8 + examples/o2mrecur/ent/ent.go | 11 + examples/o2mrecur/ent/hook/hook.go | 61 + examples/o2mrecur/ent/mutation.go | 418 + examples/o2mrecur/ent/node/node.go | 8 +- examples/o2mrecur/ent/node_create.go | 62 +- examples/o2mrecur/ent/node_delete.go | 28 +- examples/o2mrecur/ent/node_update.go | 187 +- examples/o2mrecur/ent/privacy/privacy.go | 171 + examples/o2mrecur/ent/runtime.go | 13 + examples/o2mrecur/ent/runtime/runtime.go | 13 + examples/o2mrecur/ent/tx.go | 13 +- examples/o2o2types/ent/card/card.go | 11 +- examples/o2o2types/ent/card_create.go | 65 +- examples/o2o2types/ent/card_delete.go | 28 +- examples/o2o2types/ent/card_update.go | 134 +- examples/o2o2types/ent/client.go | 97 +- examples/o2o2types/ent/config.go | 9 + examples/o2o2types/ent/ent.go | 11 + examples/o2o2types/ent/hook/hook.go | 74 + examples/o2o2types/ent/mutation.go | 717 ++ examples/o2o2types/ent/privacy/privacy.go | 195 + examples/o2o2types/ent/runtime.go | 13 + examples/o2o2types/ent/runtime/runtime.go | 13 + examples/o2o2types/ent/tx.go | 15 +- examples/o2o2types/ent/user/user.go | 9 +- examples/o2o2types/ent/user_create.go | 61 +- examples/o2o2types/ent/user_delete.go | 28 +- examples/o2o2types/ent/user_update.go | 153 +- examples/o2obidi/ent/client.go | 64 +- examples/o2obidi/ent/config.go | 8 + examples/o2obidi/ent/ent.go | 11 + examples/o2obidi/ent/hook/hook.go | 61 + examples/o2obidi/ent/mutation.go | 388 + examples/o2obidi/ent/privacy/privacy.go | 171 + examples/o2obidi/ent/runtime.go | 13 + examples/o2obidi/ent/runtime/runtime.go | 13 + examples/o2obidi/ent/tx.go | 13 +- examples/o2obidi/ent/user/user.go | 9 +- examples/o2obidi/ent/user_create.go | 61 +- examples/o2obidi/ent/user_delete.go | 28 +- examples/o2obidi/ent/user_update.go | 153 +- examples/o2orecur/ent/client.go | 64 +- examples/o2orecur/ent/config.go | 8 + examples/o2orecur/ent/ent.go | 11 + examples/o2orecur/ent/hook/hook.go | 61 + examples/o2orecur/ent/mutation.go | 412 + examples/o2orecur/ent/node/node.go | 8 +- examples/o2orecur/ent/node_create.go | 63 +- examples/o2orecur/ent/node_delete.go | 28 +- examples/o2orecur/ent/node_update.go | 175 +- examples/o2orecur/ent/privacy/privacy.go | 171 + examples/o2orecur/ent/runtime.go | 13 + examples/o2orecur/ent/runtime/runtime.go | 13 + examples/o2orecur/ent/tx.go | 13 +- examples/start/ent/car/car.go | 9 +- examples/start/ent/car_create.go | 61 +- examples/start/ent/car_delete.go | 28 +- examples/start/ent/car_update.go | 127 +- examples/start/ent/client.go | 130 +- examples/start/ent/config.go | 10 + examples/start/ent/ent.go | 11 + examples/start/ent/group/group.go | 16 +- examples/start/ent/group_create.go | 56 +- examples/start/ent/group_delete.go | 28 +- examples/start/ent/group_update.go | 135 +- examples/start/ent/hook/hook.go | 87 + examples/start/ent/migrate/schema.go | 4 +- examples/start/ent/mutation.go | 1087 +++ examples/start/ent/privacy/privacy.go | 219 + examples/start/ent/runtime.go | 35 + examples/start/ent/runtime/runtime.go | 13 + examples/start/ent/tx.go | 17 +- examples/start/ent/user/user.go | 26 +- examples/start/ent/user_create.go | 81 +- examples/start/ent/user_delete.go | 28 +- examples/start/ent/user_update.go | 223 +- examples/traversal/ent/client.go | 130 +- examples/traversal/ent/config.go | 10 + examples/traversal/ent/ent.go | 11 + examples/traversal/ent/group/group.go | 8 +- examples/traversal/ent/group_create.go | 62 +- examples/traversal/ent/group_delete.go | 28 +- examples/traversal/ent/group_update.go | 161 +- examples/traversal/ent/hook/hook.go | 87 + examples/traversal/ent/mutation.go | 1305 +++ examples/traversal/ent/pet/pet.go | 8 +- examples/traversal/ent/pet_create.go | 62 +- examples/traversal/ent/pet_delete.go | 28 +- examples/traversal/ent/pet_update.go | 161 +- examples/traversal/ent/privacy/privacy.go | 219 + examples/traversal/ent/runtime.go | 13 + examples/traversal/ent/runtime/runtime.go | 13 + examples/traversal/ent/tx.go | 17 +- examples/traversal/ent/user/user.go | 15 +- examples/traversal/ent/user_create.go | 98 +- examples/traversal/ent/user_delete.go | 28 +- examples/traversal/ent/user_update.go | 312 +- go.mod | 5 +- go.sum | 14 + 549 files changed, 62895 insertions(+), 10774 deletions(-) create mode 100644 entc/gen/template/builder/mutation.tmpl create mode 100644 entc/gen/template/hook.tmpl create mode 100644 entc/gen/template/privacy.tmpl create mode 100644 entc/gen/template/runtime.tmpl create mode 100644 entc/integration/config/ent/hook/hook.go create mode 100644 entc/integration/config/ent/mutation.go create mode 100644 entc/integration/config/ent/privacy/privacy.go create mode 100644 entc/integration/config/ent/runtime.go create mode 100644 entc/integration/config/ent/runtime/runtime.go create mode 100644 entc/integration/customid/ent/hook/hook.go create mode 100644 entc/integration/customid/ent/mutation.go create mode 100644 entc/integration/customid/ent/privacy/privacy.go create mode 100644 entc/integration/customid/ent/runtime.go create mode 100644 entc/integration/customid/ent/runtime/runtime.go create mode 100644 entc/integration/ent/hook/hook.go create mode 100644 entc/integration/ent/mutation.go create mode 100644 entc/integration/ent/privacy/privacy.go create mode 100644 entc/integration/ent/runtime.go create mode 100644 entc/integration/ent/runtime/runtime.go create mode 100644 entc/integration/gremlin/ent/hook/hook.go create mode 100644 entc/integration/gremlin/ent/mutation.go create mode 100644 entc/integration/gremlin/ent/privacy/privacy.go create mode 100644 entc/integration/gremlin/ent/runtime.go create mode 100644 entc/integration/gremlin/ent/runtime/runtime.go create mode 100644 entc/integration/hooks/ent/card.go create mode 100644 entc/integration/hooks/ent/card/card.go create mode 100644 entc/integration/hooks/ent/card/where.go create mode 100644 entc/integration/hooks/ent/card_create.go create mode 100644 entc/integration/hooks/ent/card_delete.go create mode 100644 entc/integration/hooks/ent/card_query.go create mode 100644 entc/integration/hooks/ent/card_update.go create mode 100644 entc/integration/hooks/ent/client.go create mode 100644 entc/integration/hooks/ent/config.go create mode 100644 entc/integration/hooks/ent/context.go create mode 100644 entc/integration/hooks/ent/ent.go create mode 100644 entc/integration/hooks/ent/generate.go create mode 100644 entc/integration/hooks/ent/hook/hook.go create mode 100644 entc/integration/hooks/ent/migrate/migrate.go create mode 100644 entc/integration/hooks/ent/migrate/schema.go create mode 100644 entc/integration/hooks/ent/mutation.go create mode 100644 entc/integration/hooks/ent/predicate/predicate.go create mode 100644 entc/integration/hooks/ent/privacy/privacy.go create mode 100644 entc/integration/hooks/ent/runtime.go create mode 100644 entc/integration/hooks/ent/runtime/runtime.go create mode 100644 entc/integration/hooks/ent/schema/card.go create mode 100644 entc/integration/hooks/ent/schema/user.go create mode 100644 entc/integration/hooks/ent/tx.go create mode 100644 entc/integration/hooks/ent/user.go create mode 100644 entc/integration/hooks/ent/user/user.go create mode 100644 entc/integration/hooks/ent/user/where.go create mode 100644 entc/integration/hooks/ent/user_create.go create mode 100644 entc/integration/hooks/ent/user_delete.go create mode 100644 entc/integration/hooks/ent/user_query.go create mode 100644 entc/integration/hooks/ent/user_update.go create mode 100644 entc/integration/hooks/hooks_test.go create mode 100644 entc/integration/hooks/main.go create mode 100644 entc/integration/idtype/ent/hook/hook.go create mode 100644 entc/integration/idtype/ent/mutation.go create mode 100644 entc/integration/idtype/ent/privacy/privacy.go create mode 100644 entc/integration/idtype/ent/runtime.go create mode 100644 entc/integration/idtype/ent/runtime/runtime.go create mode 100644 entc/integration/json/ent/hook/hook.go create mode 100644 entc/integration/json/ent/mutation.go create mode 100644 entc/integration/json/ent/privacy/privacy.go create mode 100644 entc/integration/json/ent/runtime.go create mode 100644 entc/integration/json/ent/runtime/runtime.go create mode 100644 entc/integration/migrate/entv1/hook/hook.go create mode 100644 entc/integration/migrate/entv1/mutation.go create mode 100644 entc/integration/migrate/entv1/privacy/privacy.go create mode 100644 entc/integration/migrate/entv1/runtime.go create mode 100644 entc/integration/migrate/entv1/runtime/runtime.go create mode 100644 entc/integration/migrate/entv2/hook/hook.go create mode 100644 entc/integration/migrate/entv2/mutation.go create mode 100644 entc/integration/migrate/entv2/privacy/privacy.go create mode 100644 entc/integration/migrate/entv2/runtime.go create mode 100644 entc/integration/migrate/entv2/runtime/runtime.go create mode 100644 entc/integration/privacy/ent/client.go create mode 100644 entc/integration/privacy/ent/config.go create mode 100644 entc/integration/privacy/ent/context.go create mode 100644 entc/integration/privacy/ent/ent.go create mode 100644 entc/integration/privacy/ent/generate.go create mode 100644 entc/integration/privacy/ent/hook/hook.go create mode 100644 entc/integration/privacy/ent/migrate/migrate.go create mode 100644 entc/integration/privacy/ent/migrate/schema.go create mode 100644 entc/integration/privacy/ent/mutation.go create mode 100644 entc/integration/privacy/ent/planet.go create mode 100644 entc/integration/privacy/ent/planet/planet.go create mode 100644 entc/integration/privacy/ent/planet/where.go create mode 100644 entc/integration/privacy/ent/planet_create.go create mode 100644 entc/integration/privacy/ent/planet_delete.go create mode 100644 entc/integration/privacy/ent/planet_query.go create mode 100644 entc/integration/privacy/ent/planet_update.go create mode 100644 entc/integration/privacy/ent/predicate/predicate.go create mode 100644 entc/integration/privacy/ent/privacy/privacy.go create mode 100644 entc/integration/privacy/ent/runtime.go create mode 100644 entc/integration/privacy/ent/runtime/runtime.go create mode 100644 entc/integration/privacy/ent/schema/planet.go create mode 100644 entc/integration/privacy/ent/tx.go create mode 100644 entc/integration/privacy/privacy_test.go create mode 100644 entc/integration/privacy/rule/rule.go create mode 100644 entc/integration/template/ent/hook/hook.go create mode 100644 entc/integration/template/ent/mutation.go create mode 100644 entc/integration/template/ent/privacy/privacy.go create mode 100644 entc/integration/template/ent/runtime.go create mode 100644 entc/integration/template/ent/runtime/runtime.go create mode 100644 examples/edgeindex/ent/hook/hook.go create mode 100644 examples/edgeindex/ent/mutation.go create mode 100644 examples/edgeindex/ent/privacy/privacy.go create mode 100644 examples/edgeindex/ent/runtime.go create mode 100644 examples/edgeindex/ent/runtime/runtime.go create mode 100644 examples/entcpkg/ent/hook/hook.go create mode 100644 examples/entcpkg/ent/mutation.go create mode 100644 examples/entcpkg/ent/privacy/privacy.go create mode 100644 examples/entcpkg/ent/runtime.go create mode 100644 examples/entcpkg/ent/runtime/runtime.go create mode 100644 examples/m2m2types/ent/hook/hook.go create mode 100644 examples/m2m2types/ent/mutation.go create mode 100644 examples/m2m2types/ent/privacy/privacy.go create mode 100644 examples/m2m2types/ent/runtime.go create mode 100644 examples/m2m2types/ent/runtime/runtime.go create mode 100644 examples/m2mbidi/ent/hook/hook.go create mode 100644 examples/m2mbidi/ent/mutation.go create mode 100644 examples/m2mbidi/ent/privacy/privacy.go create mode 100644 examples/m2mbidi/ent/runtime.go create mode 100644 examples/m2mbidi/ent/runtime/runtime.go create mode 100644 examples/m2mrecur/ent/hook/hook.go create mode 100644 examples/m2mrecur/ent/mutation.go create mode 100644 examples/m2mrecur/ent/privacy/privacy.go create mode 100644 examples/m2mrecur/ent/runtime.go create mode 100644 examples/m2mrecur/ent/runtime/runtime.go create mode 100644 examples/o2m2types/ent/hook/hook.go create mode 100644 examples/o2m2types/ent/mutation.go create mode 100644 examples/o2m2types/ent/privacy/privacy.go create mode 100644 examples/o2m2types/ent/runtime.go create mode 100644 examples/o2m2types/ent/runtime/runtime.go create mode 100644 examples/o2mrecur/ent/hook/hook.go create mode 100644 examples/o2mrecur/ent/mutation.go create mode 100644 examples/o2mrecur/ent/privacy/privacy.go create mode 100644 examples/o2mrecur/ent/runtime.go create mode 100644 examples/o2mrecur/ent/runtime/runtime.go create mode 100644 examples/o2o2types/ent/hook/hook.go create mode 100644 examples/o2o2types/ent/mutation.go create mode 100644 examples/o2o2types/ent/privacy/privacy.go create mode 100644 examples/o2o2types/ent/runtime.go create mode 100644 examples/o2o2types/ent/runtime/runtime.go create mode 100644 examples/o2obidi/ent/hook/hook.go create mode 100644 examples/o2obidi/ent/mutation.go create mode 100644 examples/o2obidi/ent/privacy/privacy.go create mode 100644 examples/o2obidi/ent/runtime.go create mode 100644 examples/o2obidi/ent/runtime/runtime.go create mode 100644 examples/o2orecur/ent/hook/hook.go create mode 100644 examples/o2orecur/ent/mutation.go create mode 100644 examples/o2orecur/ent/privacy/privacy.go create mode 100644 examples/o2orecur/ent/runtime.go create mode 100644 examples/o2orecur/ent/runtime/runtime.go create mode 100644 examples/start/ent/hook/hook.go create mode 100644 examples/start/ent/mutation.go create mode 100644 examples/start/ent/privacy/privacy.go create mode 100644 examples/start/ent/runtime.go create mode 100644 examples/start/ent/runtime/runtime.go create mode 100644 examples/traversal/ent/hook/hook.go create mode 100644 examples/traversal/ent/mutation.go create mode 100644 examples/traversal/ent/privacy/privacy.go create mode 100644 examples/traversal/ent/runtime.go create mode 100644 examples/traversal/ent/runtime/runtime.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 63c2d3521..1da177819 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,7 @@ aliases: orbs: aws-cli: circleci/aws-cli@0.1.13 - go: circleci/go@0.2.0 + go: circleci/go@1.1.0 commands: getmods: @@ -33,7 +33,9 @@ jobs: command: golangci-lint run --out-format junit-xml > ~/test-results/lint.xml - *storetestdir unit: - executor: go/default + executor: + name: go/default + tag: '1.14' steps: - checkout - *mktestdir diff --git a/dialect/gremlin/encoding/graphson/bench_test.go b/dialect/gremlin/encoding/graphson/bench_test.go index 158ad76c7..e6c48fffa 100644 --- a/dialect/gremlin/encoding/graphson/bench_test.go +++ b/dialect/gremlin/encoding/graphson/bench_test.go @@ -7,7 +7,7 @@ package graphson import ( "testing" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" ) type book struct { diff --git a/dialect/gremlin/encoding/graphson/common_test.go b/dialect/gremlin/encoding/graphson/common_test.go index 7bd2f4701..6014a4d7f 100644 --- a/dialect/gremlin/encoding/graphson/common_test.go +++ b/dialect/gremlin/encoding/graphson/common_test.go @@ -7,7 +7,7 @@ package graphson import ( "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/stretchr/testify/mock" ) diff --git a/dialect/gremlin/encoding/graphson/decode.go b/dialect/gremlin/encoding/graphson/decode.go index 1b28da5d6..9adee0a82 100644 --- a/dialect/gremlin/encoding/graphson/decode.go +++ b/dialect/gremlin/encoding/graphson/decode.go @@ -8,7 +8,7 @@ import ( "io" "reflect" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" ) diff --git a/dialect/gremlin/encoding/graphson/encode.go b/dialect/gremlin/encoding/graphson/encode.go index 3230df105..99756c360 100644 --- a/dialect/gremlin/encoding/graphson/encode.go +++ b/dialect/gremlin/encoding/graphson/encode.go @@ -8,7 +8,7 @@ import ( "io" "reflect" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" ) diff --git a/dialect/gremlin/encoding/graphson/error.go b/dialect/gremlin/encoding/graphson/error.go index 4c7157337..a54a22ecf 100644 --- a/dialect/gremlin/encoding/graphson/error.go +++ b/dialect/gremlin/encoding/graphson/error.go @@ -7,7 +7,7 @@ package graphson import ( "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/extension.go b/dialect/gremlin/encoding/graphson/extension.go index c911a1799..5b624f7cd 100644 --- a/dialect/gremlin/encoding/graphson/extension.go +++ b/dialect/gremlin/encoding/graphson/extension.go @@ -7,7 +7,7 @@ package graphson import ( "reflect" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" ) diff --git a/dialect/gremlin/encoding/graphson/init.go b/dialect/gremlin/encoding/graphson/init.go index 6ec6eda50..98253c934 100644 --- a/dialect/gremlin/encoding/graphson/init.go +++ b/dialect/gremlin/encoding/graphson/init.go @@ -5,7 +5,7 @@ package graphson import ( - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" ) var config = jsoniter.Config{}.Froze() diff --git a/dialect/gremlin/encoding/graphson/interface.go b/dialect/gremlin/encoding/graphson/interface.go index 8e3804409..8bca42043 100644 --- a/dialect/gremlin/encoding/graphson/interface.go +++ b/dialect/gremlin/encoding/graphson/interface.go @@ -11,7 +11,7 @@ import ( "reflect" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/lazy.go b/dialect/gremlin/encoding/graphson/lazy.go index ec011145e..67a0b5e30 100644 --- a/dialect/gremlin/encoding/graphson/lazy.go +++ b/dialect/gremlin/encoding/graphson/lazy.go @@ -8,7 +8,7 @@ import ( "sync" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/lazy_test.go b/dialect/gremlin/encoding/graphson/lazy_test.go index 533332d80..a39dea505 100644 --- a/dialect/gremlin/encoding/graphson/lazy_test.go +++ b/dialect/gremlin/encoding/graphson/lazy_test.go @@ -8,7 +8,7 @@ import ( "sync/atomic" "testing" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/dialect/gremlin/encoding/graphson/map.go b/dialect/gremlin/encoding/graphson/map.go index 8430632a2..de4155197 100644 --- a/dialect/gremlin/encoding/graphson/map.go +++ b/dialect/gremlin/encoding/graphson/map.go @@ -7,7 +7,7 @@ package graphson import ( "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" ) diff --git a/dialect/gremlin/encoding/graphson/map_test.go b/dialect/gremlin/encoding/graphson/map_test.go index 593276c90..1bfbe6ffe 100644 --- a/dialect/gremlin/encoding/graphson/map_test.go +++ b/dialect/gremlin/encoding/graphson/map_test.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/dialect/gremlin/encoding/graphson/marshaler.go b/dialect/gremlin/encoding/graphson/marshaler.go index 26dea88fd..4599995e7 100644 --- a/dialect/gremlin/encoding/graphson/marshaler.go +++ b/dialect/gremlin/encoding/graphson/marshaler.go @@ -9,7 +9,7 @@ import ( "io" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/marshaler_test.go b/dialect/gremlin/encoding/graphson/marshaler_test.go index a5eace8bb..191776d9b 100644 --- a/dialect/gremlin/encoding/graphson/marshaler_test.go +++ b/dialect/gremlin/encoding/graphson/marshaler_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/dialect/gremlin/encoding/graphson/native.go b/dialect/gremlin/encoding/graphson/native.go index 8375e3bb7..9e26041dc 100644 --- a/dialect/gremlin/encoding/graphson/native.go +++ b/dialect/gremlin/encoding/graphson/native.go @@ -11,7 +11,7 @@ import ( "reflect" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" ) diff --git a/dialect/gremlin/encoding/graphson/native_test.go b/dialect/gremlin/encoding/graphson/native_test.go index 4338a9ff4..14ceab4b5 100644 --- a/dialect/gremlin/encoding/graphson/native_test.go +++ b/dialect/gremlin/encoding/graphson/native_test.go @@ -9,7 +9,7 @@ import ( "math" "testing" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/dialect/gremlin/encoding/graphson/slice.go b/dialect/gremlin/encoding/graphson/slice.go index 3a5978660..ac15f0c39 100644 --- a/dialect/gremlin/encoding/graphson/slice.go +++ b/dialect/gremlin/encoding/graphson/slice.go @@ -9,7 +9,7 @@ import ( "reflect" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/struct.go b/dialect/gremlin/encoding/graphson/struct.go index 226ab1ff9..429570255 100644 --- a/dialect/gremlin/encoding/graphson/struct.go +++ b/dialect/gremlin/encoding/graphson/struct.go @@ -4,9 +4,7 @@ package graphson -import ( - "github.com/json-iterator/go" -) +import jsoniter "github.com/json-iterator/go" // DecoratorOfStructField decorates a struct field value encoder. func (encodeExtension) DecoratorOfStructField(enc jsoniter.ValEncoder, tag string) jsoniter.ValEncoder { diff --git a/dialect/gremlin/encoding/graphson/time.go b/dialect/gremlin/encoding/graphson/time.go index 6ea4a5d52..e0bfe7156 100644 --- a/dialect/gremlin/encoding/graphson/time.go +++ b/dialect/gremlin/encoding/graphson/time.go @@ -8,7 +8,7 @@ import ( "time" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" ) func init() { diff --git a/dialect/gremlin/encoding/graphson/type.go b/dialect/gremlin/encoding/graphson/type.go index 21942310b..34240704a 100644 --- a/dialect/gremlin/encoding/graphson/type.go +++ b/dialect/gremlin/encoding/graphson/type.go @@ -9,7 +9,7 @@ import ( "strings" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/util.go b/dialect/gremlin/encoding/graphson/util.go index 1825ed02e..35d27e6b7 100644 --- a/dialect/gremlin/encoding/graphson/util.go +++ b/dialect/gremlin/encoding/graphson/util.go @@ -8,7 +8,7 @@ import ( "io" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" ) diff --git a/dialect/gremlin/encoding/graphson/util_test.go b/dialect/gremlin/encoding/graphson/util_test.go index e0471a2ce..35db8332c 100644 --- a/dialect/gremlin/encoding/graphson/util_test.go +++ b/dialect/gremlin/encoding/graphson/util_test.go @@ -11,7 +11,7 @@ import ( "testing" "unsafe" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/dialect/gremlin/expand.go b/dialect/gremlin/expand.go index 4ffe7f600..6398598a4 100644 --- a/dialect/gremlin/expand.go +++ b/dialect/gremlin/expand.go @@ -9,7 +9,7 @@ import ( "sort" "strings" - "github.com/json-iterator/go" + jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" ) diff --git a/ent.go b/ent.go index db202fca5..fd1f0b630 100644 --- a/ent.go +++ b/ent.go @@ -6,6 +6,9 @@ package ent import ( + "context" + "fmt" + "github.com/facebookincubator/ent/schema/edge" "github.com/facebookincubator/ent/schema/field" "github.com/facebookincubator/ent/schema/index" @@ -47,6 +50,11 @@ type ( // Mixin returns an optional list of Mixin to extends // the schema. Mixin() []Mixin + // Hooks returns an optional list of Hook to apply on + // mutations. + Hooks() []Hook + // Policy returns the privacy policy of the schema. + Policy() Policy } // A Field interface returns a field descriptor for vertex fields/properties. @@ -135,6 +143,25 @@ type ( Fields() []Field } + // The Policy type defines the write privacy policy of an entity. + // The usage for the interface is as follows: + // + // type T struct { + // ent.Schema + // } + // + // func(T) Policy() ent.Policy { + // return privacy.AlwaysAllowReadWrite() + // } + // + // + Policy interface { + EvalWrite(context.Context, Mutation) error + // Note that the read policy is under development + // and is currently disabled. + // EvalRead(context.Context, Value) error + } + // Schema is the default implementation for the schema Interface. // It can be embedded in end-user schemas as follows: // @@ -161,3 +188,150 @@ func (Schema) Config() Config { return Config{} } // Mixin of the schema. func (Schema) Mixin() []Mixin { return nil } + +// Hooks of the schema. +func (Schema) Hooks() []Hook { return nil } + +// Policy of the schema. +func (Schema) Policy() Policy { return nil } + +type ( + // Value represents a value returned by ent. + Value interface{} + // Mutation represents an operation that mutate the graph. + // For example, adding a new node, updating many, or dropping + // data. The implementation is generated by entc (ent codegen). + Mutation interface { + // Op returns the operation name generated by entc. + Op() Op + // Type returns the schema type for this mutation. + Type() string + + // Fields returns all fields that were changed during + // this mutation. Note that, in order to get all numeric + // fields that were in/decremented, call AddedFields(). + Fields() []string + // Field returns the value of a field with the given name. + // The second boolean value indicates that this field was + // not set, or was not define in the schema. + Field(name string) (Value, bool) + // SetField sets the value for the given name. It returns an + // error if the field is not defined in the schema, or if the + // type mismatch the field type. + SetField(name string, value Value) error + + // AddedFields returns all numeric fields that were incremented + // or decremented during this mutation. + AddedFields() []string + // AddedField returns the numeric value that was in/decremented + // from a field with the given name. The second value indicates + // that this field was not set, or was not define in the schema. + AddedField(name string) (Value, bool) + // AddField adds the value for the given name. It returns an + // error if the field is not defined in the schema, or if the + // type mismatch the field type. + AddField(name string, value Value) error + + // ClearedFields returns all nullable fields that were cleared + // during this mutation. + ClearedFields() []string + // FieldCleared returns a boolean indicates if this field was + // cleared in this mutation. + FieldCleared(name string) bool + // ClearField clears the value for the given name. It returns an + // error if the field is not defined in the schema. + ClearField(name string) error + + // ResetField resets all changes in the mutation regarding the + // given field name. It returns an error if the field is not + // defined in the schema. + ResetField(name string) error + + // AddedEdges returns all edge names that were set/added in this + // mutation. + AddedEdges() []string + // AddedIDs returns all ids (to other nodes) that were added for + // the given edge name. + AddedIDs(name string) []Value + + // RemovedEdges returns all edge names that were removed in this + // mutation. + RemovedEdges() []string + // RemovedIDs returns all ids (to other nodes) that were removed for + // the given edge name. + RemovedIDs(name string) []Value + + // ClearedEdges returns all edge names that were cleared in this + // mutation. + ClearedEdges() []string + // EdgeCleared returns a boolean indicates if this edge was + // cleared in this mutation. + EdgeCleared(name string) bool + // ClearEdge clears the value for the given name. It returns an + // error if the edge name is not defined in the schema. + ClearEdge(name string) error + + // ResetEdge resets all changes in the mutation regarding the + // given edge name. It returns an error if the edge is not + // defined in the schema. + ResetEdge(name string) error + } + + // Mutator is the interface that wraps the Mutate method. + Mutator interface { + // Mutate apply the given mutation on the graph. + Mutate(context.Context, Mutation) (Value, error) + } + + // The MutateFunc type is an adapter to allow the use of ordinary + // function as mutator. If f is a function with the appropriate signature, + // MutateFunc(f) is a Mutator that calls f. + MutateFunc func(context.Context, Mutation) (Value, error) + + // Hook defines the "mutation middleware". A function that gets a Mutator + // and returns a Mutator. For example: + // + // hook := func(next ent.Mutator) ent.Mutator { + // return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + // fmt.Printf("Type: %s, Operation: %s, ConcreteType: %T\n", m.Type(), m.Op(), m) + // return next.Mutate(ctx, m) + // }) + // } + // + Hook func(Mutator) Mutator +) + +// Mutate calls f(ctx, m). +func (f MutateFunc) Mutate(ctx context.Context, m Mutation) (Value, error) { + return f(ctx, m) +} + +// An Op represents a mutation operation. +type Op uint + +// Mutation operations. +const ( + OpCreate Op = 1 << iota // node creation. + OpUpdate // update nodes by predicate (if any). + OpUpdateOne // update one node. + OpDelete // delete nodes by predicate (if any). + OpDeleteOne // delete one one. +) + +// Is reports whether o is match the given operation. +func (op Op) Is(o Op) bool { return op&o != 0 } + +func (op Op) String() string { + if op > 0 || op < Op(len(ops)) { + return ops[op] + } + return fmt.Sprintf("op(%d)", op) +} + +var ops = [...]string{ + OpCreate: "Create", + OpUpdate: "Update", + OpUpdateOne: "UpdateOne", + OpDelete: "Delete", + OpDeleteOne: "DeleteOne", +} diff --git a/entc/entc.go b/entc/entc.go index cb39fc932..9e1760dbc 100644 --- a/entc/entc.go +++ b/entc/entc.go @@ -18,7 +18,7 @@ import ( ) // LoadGraph loads the schema package from the given schema path, -// and construct a *gen.Graph. +// and constructs a *gen.Graph. func LoadGraph(schemaPath string, cfg *gen.Config) (*gen.Graph, error) { spec, err := (&load.Config{Path: schemaPath}).Load() if err != nil { @@ -27,7 +27,7 @@ func LoadGraph(schemaPath string, cfg *gen.Config) (*gen.Graph, error) { cfg.Schema = spec.PkgPath if cfg.Package == "" { // default package-path for codegen is one package - // above the schema package (`/ent/schema`). + // before the schema package (`/ent/schema`). cfg.Package = path.Dir(spec.PkgPath) } return gen.NewGraph(cfg, spec.Schemas...) @@ -45,7 +45,7 @@ func LoadGraph(schemaPath string, cfg *gen.Config) (*gen.Graph, error) { // IDType: &field.TypeInfo{Type: field.TypeInt}, // }) // -func Generate(schemaPath string, cfg *gen.Config, options ...Option) error { +func Generate(schemaPath string, cfg *gen.Config, options ...Option) (err error) { if cfg.Target == "" { abs, err := filepath.Abs(schemaPath) if err != nil { @@ -67,6 +67,15 @@ func Generate(schemaPath string, cfg *gen.Config, options ...Option) error { } cfg.Storage = driver } + undo, err := gen.PrepareEnv(cfg) + if err != nil { + return err + } + defer func() { + if err != nil { + _ = undo() + } + }() graph, err := LoadGraph(schemaPath, cfg) if err != nil { return err diff --git a/entc/gen/func.go b/entc/gen/func.go index 77f476a09..95a259860 100644 --- a/entc/gen/func.go +++ b/entc/gen/func.go @@ -29,6 +29,7 @@ var ( "append": reflect.Append, "appends": reflect.AppendSlice, "order": order, + "camel": camel, "snake": snake, "pascal": pascal, "extend": extend, @@ -120,6 +121,20 @@ func pascal(s string) string { return strings.Join(words, "") } +// camel converts the given column name into a camelCase. +// +// user_info => userInfo +// full_name => fullName +// user_id => userID +// +func camel(s string) string { + words := strings.SplitN(s, "_", 2) + if len(words) == 1 { + return strings.ToLower(words[0]) + } + return strings.ToLower(words[0]) + pascal(words[1]) +} + // snake converts the given struct or field name into a snake_case. // // Username => username @@ -208,6 +223,11 @@ func extend(v interface{}, kv ...interface{}) (interface{}, error) { scope[k] = v.Scope[k] } return &typeScope{Type: v.Type, Scope: scope}, nil + case *graphScope: + for k := range v.Scope { + scope[k] = v.Scope[k] + } + return &graphScope{Graph: v.Graph, Scope: scope}, nil default: return nil, fmt.Errorf("invalid type for extend: %T", v) } diff --git a/entc/gen/graph.go b/entc/gen/graph.go index e30dd5a87..2c3c849c4 100644 --- a/entc/gen/graph.go +++ b/entc/gen/graph.go @@ -8,9 +8,12 @@ package gen import ( "bytes" "fmt" + "go/parser" + "go/token" "io/ioutil" "os" "path/filepath" + "runtime/debug" "text/template" "text/template/parse" @@ -22,13 +25,13 @@ import ( ) type ( - // Config for global generator configuration that similar for all nodes. + // Config for global codegen to be shared between all nodes. Config struct { - // Schema is the package path for the schema directory. + // Schema is the package path for the schema package. Schema string - // Target is the path for the directory that holding the generated code. + // Target is the filepath for the directory that holds the generated code. Target string - // Package name for the targeted directory that holds the generated code. + // Package path for the targeted directory that holds the generated code. Package string // Header is an optional header signature for generated files. Header string @@ -215,7 +218,7 @@ func resolve(t *Type) error { case e.IsInverse(): ref, ok := e.Type.HasAssoc(e.Inverse) if !ok { - return fmt.Errorf("edge is missing for inverse edge: %s.%s", e.Type.Name, e.Name) + return fmt.Errorf("edge %q is missing for inverse edge: %s.%s", e.Inverse, e.Type.Name, e.Name) } if !e.Optional && !ref.Optional { return fmt.Errorf("edges cannot be required in both directions: %s.%s <-> %s.%s", t.Name, e.Name, e.Type.Name, ref.Name) @@ -409,6 +412,43 @@ func (g *Graph) templates() (*template.Template, []GraphTemplate) { return templates, external } +// ModuleInfo returns the entc binary module version. +func (Config) ModuleInfo() (m debug.Module) { + info, ok := debug.ReadBuildInfo() + if ok { + m = info.Main + } + return +} + +// PrepareEnv makes sure the generated directory (environment) +// is suitable for loading the `ent` package (avoid cyclic imports). +func PrepareEnv(c *Config) (undo func() error, err error) { + var ( + nop = func() error { return nil } + path = filepath.Join(c.Target, "runtime.go") + ) + out, err := ioutil.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + return nop, nil + } + return nil, err + } + fi, err := parser.ParseFile(token.NewFileSet(), path, out, parser.ImportsOnly) + if err != nil { + return nil, err + } + // Targeted package doesn't import the schema. + if len(fi.Imports) == 0 { + return nop, nil + } + if err := ioutil.WriteFile(path, append([]byte("// +build tools\n"), out...), 0644); err != nil { + return nil, err + } + return func() error { return ioutil.WriteFile(path, out, 0644) }, nil +} + // formatFiles runs "goimports" on given paths. func formatFiles(paths []string) error { for _, path := range paths { diff --git a/entc/gen/internal/bindata.go b/entc/gen/internal/bindata.go index 58528f2e6..d234f53c6 100644 --- a/entc/gen/internal/bindata.go +++ b/entc/gen/internal/bindata.go @@ -3,6 +3,7 @@ // template/base.tmpl // template/builder/create.tmpl // template/builder/delete.tmpl +// template/builder/mutation.tmpl // template/builder/query.tmpl // template/builder/setter.tmpl // template/builder/update.tmpl @@ -37,11 +38,14 @@ // template/dialect/sql/update.tmpl // template/ent.tmpl // template/header.tmpl +// template/hook.tmpl // template/import.tmpl // template/meta.tmpl // template/migrate/migrate.tmpl // template/migrate/schema.tmpl // template/predicate.tmpl +// template/privacy.tmpl +// template/runtime.tmpl // template/tx.tmpl // template/where.tmpl package internal @@ -120,7 +124,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templateBaseTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x5d\x4f\xdd\x38\x13\xbe\x3e\xf9\x15\xa3\xe8\xbc\x55\x42\x0f\x09\xe5\xee\xad\xc4\x05\x65\xcb\x0a\xa9\xcb\xae\x44\x57\xbd\xa8\xaa\x95\x49\x26\x89\x45\x62\x07\xdb\x01\x8e\xa2\xfc\xf7\xd5\xd8\xf9\x3a\xe1\x14\x68\xe9\xde\xa0\x13\x7f\x3c\xf3\xcc\xcc\x33\x63\x9b\xb6\x8d\x0f\xbc\x33\x59\x6f\x15\xcf\x0b\x03\xc7\x47\xef\xfe\x7f\x58\x2b\xd4\x28\x0c\x9c\xb3\x04\xaf\xa5\xbc\x81\x0b\x91\x44\x70\x5a\x96\x60\x17\x69\xa0\x79\x75\x87\x69\xe4\x7d\x2e\xb8\x06\x2d\x1b\x95\x20\x24\x32\x45\xe0\x1a\x4a\x9e\xa0\xd0\x98\x42\x23\x52\x54\x60\x0a\x84\xd3\x9a\x25\x05\xc2\x71\x74\x34\xcc\x42\x26\x1b\x91\x7a\x5c\xd8\xf9\x4f\x17\x67\x1f\x2f\xaf\x3e\x42\xc6\x4b\x84\x7e\x4c\x49\x69\x20\xe5\x0a\x13\x23\xd5\x16\x64\x06\x66\x66\xcc\x28\xc4\xc8\x3b\x88\xbb\xce\xf3\xda\x16\x52\xcc\xb8\x40\xf0\xaf\x99\x46\x1f\xfa\xc1\x75\x7d\x93\xc3\xfb\x13\xa0\x41\x58\x47\x67\x52\x64\x3c\x8f\xfe\x62\xc9\x0d\xcb\x91\x16\xb5\x2d\x18\xac\xea\x92\x19\x04\xbf\x40\x96\xa2\xf2\x61\x3d\x6c\x9f\xa6\x78\x55\x4b\x65\x86\xa9\x38\x86\x3f\x15\x79\xc6\xea\xba\xe4\xa8\x81\x09\x90\x34\xc0\x45\x0e\x52\x00\x72\x53\xa0\x82\x5c\xb1\xba\x00\xa3\xd8\x1d\x2a\xcd\x4a\x90\x0a\xf4\x6d\x09\x1a\x4b\xeb\x51\xe4\x99\x6d\x8d\x3d\x52\xd6\x88\x24\x20\xc6\xd1\x95\x91\x8a\xe5\x18\x7d\x68\x78\x49\x33\x5d\x17\x5a\x32\x8a\x89\x1c\x61\x9d\x6d\x60\x6d\x6d\x91\x5f\xee\x47\xd7\x79\x2b\xda\x9a\xc1\x09\xd4\x4c\x27\xac\xa4\xdf\x34\x1a\xc7\xe0\x26\xba\x6e\xe4\x4a\x91\xcd\xf9\x1d\x0a\xc8\x38\x96\xa9\xa6\x68\xb7\x2d\x34\x75\x8d\xaa\x5f\x6a\x61\x23\x6f\x45\xa4\x46\x80\xa0\x5f\x1e\x45\x91\x36\xe4\x69\xd8\x53\x6f\xbd\xd5\xaa\x6d\x0f\xe1\x9e\x9b\x02\xf0\xc1\xa0\x48\x21\xe0\x22\xc5\x07\x58\x47\x97\x32\x45\x0d\x47\x21\xf8\xe7\x8d\x48\x7c\x82\xf2\xed\x36\x7f\x70\xe3\x90\x88\xae\xac\x03\xa6\xaa\x4b\x72\xab\x56\x5c\x98\x0c\xfc\x94\x33\x0a\x55\xfc\x3f\x1d\xcb\x7e\xcf\x10\x1e\x70\xbb\x14\x9a\x46\x59\xfe\x0f\x63\xb2\x1c\x4c\xe4\x56\xb4\x2d\x10\x1f\x6b\xc4\xa6\x9b\xbe\x06\x75\x3c\x61\x2f\x57\xb2\xa9\x63\xcd\x73\xc1\x4c\xa3\x70\x61\x39\x8e\xe1\x34\xcf\x15\xe6\x64\x6f\x26\x02\xd6\x0f\x72\x29\x40\x1b\xac\x49\x0c\x36\xde\x84\x76\x78\xbd\x9d\xc4\x10\x4f\x2a\xf8\x1e\x79\xab\xb3\x53\x4d\x05\xc5\xa0\xd6\xd8\xa4\x72\xc7\x00\x65\xc7\xfd\x90\x0a\x14\x0a\x56\x91\xfc\x98\x90\x56\x7c\xee\xef\xb0\x46\xbb\xec\x24\x8d\x36\xb2\x02\xc1\x2a\xd4\x11\x9c\x4b\x05\xf8\xc0\xaa\xba\xc4\xf7\x5e\x1c\x7b\x71\xbc\xfa\x9d\x88\x7e\xd8\xba\x5c\xbf\xdb\x38\x89\x1c\x87\x11\xcd\x8d\x1e\x07\x43\x65\x75\x5d\x74\xaa\xe7\x5f\x57\x4d\xd5\x6f\x0d\x37\xe0\xeb\xa6\xfa\xc7\x7d\xf9\xe1\x06\x5e\xb0\xeb\x78\x67\xd7\xb1\x1f\x3a\xc3\x57\x09\x13\x41\x62\x1e\x36\xf0\xe6\x2e\x24\xa2\x56\x97\xa7\x3a\xc8\xc4\x94\x86\x8d\xcd\xec\xa0\xcc\x29\x3b\xad\x67\xc5\xe9\xe2\xfa\x44\xaa\x99\x5e\xaa\xeb\x19\x6d\x75\xf3\xaa\xa4\x88\x6e\x60\x4d\x41\x3e\x27\xee\xa4\x2a\x36\x72\x18\x0b\x54\x58\xb5\xf5\x25\x4a\x7b\xc6\xa9\x67\xa5\x98\x48\xa1\xcd\x92\x62\xdb\x02\xcf\xa0\x60\xfa\xf3\x2e\xc1\x41\xfa\xcf\x94\xe4\x25\xab\x48\xd9\x96\xc8\x58\x9f\x62\x56\x91\x4f\x17\x55\xcf\x60\xa8\xa8\xb1\xdb\x88\x65\xbb\x69\x5b\xb8\x6d\xa4\xc1\xd1\xe7\xfd\x3a\x96\x36\xd8\x3c\x9b\xc7\xb1\xeb\x16\xfd\x8a\x8e\x81\xd1\x28\xb2\xa4\x70\xc5\xb5\xd3\xad\x88\x40\xb0\x07\xca\x01\x38\x8d\x8c\x18\x0b\xb1\xfc\x48\x2b\x13\xe0\x7f\x19\xe0\xfd\xb9\xa9\x97\xf5\x34\x97\xd8\xcc\x81\xfd\xb2\xc6\x16\xc7\x70\x29\xcd\x39\x1d\xae\x1f\x95\xb2\xad\x81\xa0\x34\xdc\x17\x28\xc0\xa8\x2d\x75\x09\x23\x21\x43\x93\x14\xc0\x40\xd7\x98\xf0\x8c\x27\x80\xc2\x70\xb3\x05\x26\x52\xe0\x06\xee\x99\x06\x21\x8d\x3b\xa5\x87\x13\x39\x65\x86\xd1\x59\xda\x1f\x5d\xbb\x76\xb4\x51\x4d\x62\x28\x86\x25\xbb\xc6\xb2\x8f\xb3\xe7\x28\xb9\x25\x9c\x7a\x4d\x85\xc2\x38\x5d\xa0\x1b\x14\x06\x55\xc6\x12\x8c\x5c\x61\x07\x08\x07\x3b\xc8\xa1\xdb\x1d\x84\x3d\x24\x99\xe8\xe3\xe3\x4f\x6d\xe4\x3d\xf8\xf0\x16\x30\x72\xc6\xdf\x82\x3f\xd1\xf7\x7b\x12\x17\x7a\xc0\x1d\x83\xc2\xe0\x5a\xca\x12\x99\x00\x2e\x52\x9e\x30\x43\xf8\xf7\x05\xda\xee\x39\xe3\x48\x2b\xa7\x70\xd8\xc1\x9e\xee\x04\x1a\xa0\x52\x6e\x2a\xb4\xa8\xc4\x93\x67\x34\x02\x27\x27\x20\xb8\x1d\x18\x98\x67\xac\xd4\x48\xa9\x5b\xdd\x31\x05\x4b\x97\x47\x07\x1f\x2c\x9e\xa6\x8e\x89\x4a\x6d\xe0\x0d\x86\xbd\x33\x7f\x30\x7d\x33\xba\x53\x31\x7d\x43\xf9\x52\x7b\x08\xce\x17\xce\x29\x3a\xcf\x1c\xc7\x5d\x27\xc2\x39\x51\xc1\x4b\x4b\xb3\xff\x44\xa5\xbc\x51\x65\x57\x5c\xe4\x4d\xc9\xd4\xcb\x84\xd6\x2f\x9e\x0b\xad\x92\x0a\x29\xcc\x54\xfc\x68\x35\xf7\x8c\xde\x76\x2d\xfe\x62\xc9\xed\x80\xbf\x46\x75\x83\xab\x3b\xc2\x1b\xd0\x7f\x5a\x7b\x53\x00\x97\xf2\x1b\xa0\x5f\xad\xc0\x9d\x08\xbc\x40\x84\x97\xd2\x7c\x92\x2c\xc5\xa7\x5b\x4d\x8e\xc6\xba\x90\x52\xae\xd9\xd4\x5b\x4a\xbb\x15\xe8\x5e\x54\x20\xdc\x36\xa8\xb6\x53\xa6\xe7\xb8\x53\x9e\x31\xcd\xf1\xb5\x69\x9e\x21\xff\x58\x92\xad\x71\xca\xb1\xfd\xb1\xeb\xc5\x4e\xaa\x9d\x85\x9f\x4e\x74\x1f\x97\x47\x69\x76\xb0\xaf\x4e\xf2\xcc\xff\x17\xa4\xf8\x8c\x2e\x1e\x8a\x71\x61\x9e\xcc\x71\xa2\x90\x19\x8c\x9b\x3a\xa5\xa3\x8a\xaa\x59\x2a\x57\xde\xb6\xdc\xdd\x05\x39\x25\xc0\xf9\x9c\x7d\xd3\x21\x57\x90\x8c\x56\x34\x64\x8c\x97\x98\xee\xdc\x4f\x37\x70\xc7\x65\xe9\xee\x0b\x32\x73\xf1\x97\x8a\xd0\xdc\x99\xde\x08\x7e\xdb\xa0\x40\xad\x7b\x01\x2d\x59\x4f\x0a\xaa\x74\x3e\x08\x68\x75\xaf\x58\xed\x42\xf9\x53\x62\x5a\x18\x79\xa9\x98\x26\x5f\x7b\x57\x07\x7d\x55\x7a\x10\xf5\xdf\xc2\x52\xdb\x47\x44\x47\x5f\x14\xb3\x8f\xb5\x7d\xf2\x7e\x44\xc9\x21\x05\xb3\x76\x3f\x34\xf2\x88\x26\x46\xd5\x7e\x2f\xcd\x3f\xa2\xdd\x85\x63\x8d\xc2\x51\xbd\x0b\xf8\xd7\x69\x78\x01\xf6\x9c\x88\xdb\x36\x3e\x00\x7c\xa8\xd9\x70\x30\x02\x49\xc4\xea\x11\xf2\x52\x5e\xb3\x12\x0a\x2c\x6b\x54\x3a\x02\xfb\xff\x84\xf1\xde\xb6\xf7\xda\xe6\x8c\x2c\xae\x6c\x4f\xdd\xc4\xf7\x5c\xe2\xd6\xfd\x9e\x47\xaf\xd1\xfd\x17\x45\x4b\xf2\x3f\x30\xc9\xed\x43\xe5\xd1\x0d\x37\xba\xf8\x2d\xfa\x4c\x55\xe4\x9e\xba\x37\xb8\xd5\xa3\x1e\x28\xe5\x34\x10\xf3\x54\x43\xa6\x64\xe5\x44\x40\x05\x59\xb1\xba\xcf\x37\x2d\x08\x2a\x1a\xf8\xda\x9b\xe9\xba\x6f\xae\x04\xdb\x2e\x84\xaf\xdf\xc6\x51\xca\xb3\x26\x12\x15\xbb\xc1\x60\x36\xb1\x81\xa3\x0d\x94\x28\x82\x2a\x0c\xbd\x15\x3d\x71\x1d\x59\xf7\xe0\xaa\xac\x3e\x34\x9c\xd0\x3b\x03\x45\x1a\xe8\x0d\xf0\x34\x9c\x5f\x54\xb4\x37\x77\xf7\xdf\x00\x00\x00\xff\xff\x91\x26\x29\x8f\xe6\x12\x00\x00") +var _templateBaseTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x5f\x6f\xdc\xb0\x0d\x7f\x3e\x7f\x0a\xc2\xb8\x75\x76\x7a\xb1\xd3\xbc\xad\x40\x1e\xd2\xac\xd9\x02\xb4\xe9\x80\x74\xeb\x43\x51\x0c\x8a\x4d\xfb\x84\xc8\x92\x23\xc9\x49\x0e\x86\xbf\xfb\x40\xc9\xff\xee\x72\x4d\xd2\xa6\xeb\x43\x71\x26\x25\xf2\x47\xf2\x47\x9a\x4e\xdb\xa6\x07\xc1\x99\xaa\x37\x9a\x97\x6b\x0b\xc7\x47\xef\xfe\x76\x58\x6b\x34\x28\x2d\x9c\xb3\x0c\xaf\x95\xba\x81\x0b\x99\x25\x70\x2a\x04\xb8\x43\x06\x48\xaf\xef\x30\x4f\x82\xaf\x6b\x6e\xc0\xa8\x46\x67\x08\x99\xca\x11\xb8\x01\xc1\x33\x94\x06\x73\x68\x64\x8e\x1a\xec\x1a\xe1\xb4\x66\xd9\x1a\xe1\x38\x39\x1a\xb4\x50\xa8\x46\xe6\x01\x97\x4e\xff\xe9\xe2\xec\xe3\xe5\xd5\x47\x28\xb8\x40\xe8\x65\x5a\x29\x0b\x39\xd7\x98\x59\xa5\x37\xa0\x0a\xb0\x33\x67\x56\x23\x26\xc1\x41\xda\x75\x41\xd0\xb6\x90\x63\xc1\x25\x42\x78\xcd\x0c\x86\xd0\x0b\x97\xf5\x4d\x09\xef\x4f\x80\x84\xb0\x4c\xce\x94\x2c\x78\x99\xfc\x8b\x65\x37\xac\x44\x3a\xd4\xb6\x60\xb1\xaa\x05\xb3\x08\xe1\x1a\x59\x8e\x3a\x84\xe5\x70\x7d\x52\xf1\xaa\x56\xda\x0e\xaa\x34\x05\xca\x0e\x13\x9c\x19\x34\x60\x15\xb0\x3b\xc5\x73\xf0\xa7\x20\x53\xb2\x10\x3c\xb3\x14\x47\x63\x50\xff\xd5\xb8\xcc\x24\x81\xdd\xd4\x08\x51\xb0\xf8\x52\xc3\xf0\xef\x84\x2c\x25\x5f\xea\x60\xf1\x4f\xca\xf3\x5c\x48\x82\x60\xf1\x1f\x26\x1a\x9c\x8b\x9d\x20\x58\x7c\x6e\x2c\xb3\x4a\x4f\xf2\x5e\xd0\x6b\xb8\x92\xdb\x1a\xae\x64\xaf\xc2\xf3\x46\x66\x73\x95\x13\x04\xb1\x8b\xeb\x8b\xa6\x8a\xb1\xba\x16\x1c\x0d\x30\x09\x8a\x04\x5c\x96\xa0\x24\x20\xb7\x6b\xd4\x50\x6a\x56\xaf\xc1\x6a\x76\x87\xda\x30\x01\x4a\x83\xb9\x15\x60\x50\xb8\x4a\xf5\x71\x7a\x4b\x45\x23\xb3\x88\x2a\x91\x5c\x59\xa5\x59\x89\xc9\x87\x86\x0b\xd2\x74\x5d\xec\x92\xac\x99\x2c\x11\x96\xc5\x0a\x96\xce\x17\xd5\xcb\xff\xe8\xba\x60\x41\x57\x0b\x38\x81\x9a\x99\x8c\x09\xfa\x4d\xd2\x34\x05\xaf\xe8\xba\x11\x2b\x31\xa6\xe4\x77\x28\xa1\xe0\x28\x72\x43\xd9\x6f\x5b\x68\xea\x1a\x75\x7f\xd4\x99\x4d\x82\x05\x81\x1a\x0d\x44\xfd\xf1\x24\x49\x8c\xa5\x48\xe3\x1e\x7a\x1b\x2c\x16\x6d\x7b\x08\xf7\xdc\xae\x01\x1f\x2c\xca\x1c\x22\x2e\x73\x7c\x80\x65\x72\xa9\x72\x34\x70\x14\x43\x48\xc9\x0b\xc9\x54\xe8\xae\x85\x43\x18\x87\x04\x74\xe1\x02\xb0\x55\x2d\x28\xac\x5a\x73\x69\x0b\x08\x73\xce\x28\x55\xe9\x5f\x4c\xaa\xfa\x3b\x43\x7a\xc0\xdf\xd2\x68\x1b\xed\xf0\x3f\x8c\x24\xf4\x66\x12\x7f\xa2\x6d\x81\xf0\x38\x27\x8e\xc6\xf4\x34\xb0\xfe\x09\x7f\xa5\x56\x4d\x9d\x1a\x5e\x4a\x66\x1b\x8d\x3b\x9e\xd3\x14\x4e\xcb\x52\x63\x49\xfe\x66\x24\x60\xbd\x90\x58\x65\x2c\xd6\x44\x06\x97\x6f\xb2\x76\x78\xbd\x99\xc8\x90\x4e\x2c\xf8\x19\x78\xc7\xb3\x53\x43\x83\x82\x41\x6d\xb0\xc9\xd5\x96\x03\xaa\x8e\xff\xa1\x34\x68\x94\xac\x22\xfa\x31\xa9\x1c\xf9\xfc\xff\xc3\x19\xe3\xab\x93\x35\xc6\xaa\x0a\x24\xab\xd0\x24\x70\xae\x34\xe0\x03\xab\x6a\x81\xef\x83\x34\x0d\xd2\x74\xf1\x0f\x02\xfa\x61\xe3\x6b\xfd\x6e\xe5\x29\x72\x1c\x27\xa4\x1b\x23\x8e\x86\x89\xd1\x75\xc9\xa9\x99\x3f\x5d\x35\x55\x7f\x35\x5e\x41\x68\x9a\xea\xbf\xfe\x29\x8c\x57\xf0\x82\x5b\xc7\x5b\xb7\x8e\xc3\xd8\x3b\xbe\xca\x98\x8c\x32\xfb\xb0\x82\x37\x77\x31\x01\x75\xbc\x3c\x35\x51\x21\xa7\x32\xac\x5c\x65\x07\x66\x4e\xd5\x69\x03\x47\x4e\x9f\xd7\x27\x4a\xcd\xcc\x2e\xbb\x9e\xe1\x56\x37\xef\x4a\xca\xe8\x0a\x96\x94\xe4\x73\xc2\x4e\xac\x62\x23\x86\xb1\x41\xa5\x63\x5b\xdf\xa2\x74\x67\x54\x3d\x4b\xc5\x4c\x49\x63\x77\x21\xb6\x2d\xf0\x02\xd6\xcc\x7c\xdd\x06\x38\x50\xff\x99\x96\xbc\x64\x15\x31\xdb\x01\x19\xfb\x53\xce\x3a\xf2\xe9\xa6\xea\x11\x0c\x1d\x35\x4e\x1b\xb9\x3b\x6e\xda\x16\x6e\x1b\x65\x71\x8c\x79\x3f\x8f\x95\x4b\x36\x2f\xe6\x79\xec\xba\x9d\x79\x45\xaf\xb7\xd1\x29\xb2\x6c\xed\x9b\x6b\x6b\x5a\x11\x80\x68\x8f\x29\x6f\xc0\x73\x64\xb4\xb1\x43\x96\x5f\x19\x65\x12\xc2\x6f\x83\xf9\x70\xee\xea\x65\x33\xcd\x17\xb6\xf0\xc6\xfe\xd8\x60\x4b\x53\xb8\x54\xf6\x9c\x96\x86\x8f\x5a\xbb\xd1\x40\xa6\x0c\xdc\xaf\x51\x82\xd5\x1b\x9a\x12\x56\x41\x81\x36\x5b\x03\x03\x53\x63\xc6\x0b\x9e\xd1\x7b\x8e\xdb\x0d\x30\x99\x03\xb7\x70\xcf\x0c\x48\x65\xfd\xf6\x31\x6c\x1a\x39\xb3\x8c\x76\x84\xfe\xd5\xb5\xed\xc7\x58\xdd\x64\x96\x72\x28\xd8\x35\x8a\x3e\xcf\x81\x87\xe4\x8f\x70\x9a\x35\x15\x4a\xeb\x79\x81\x5e\x28\x2d\xea\x82\x65\x98\xf8\xc6\x8e\x10\x0e\xb6\x2c\xc7\xfe\x76\x14\xf7\x26\xc9\x45\x9f\x9f\x70\x1a\x23\xef\x21\x84\xb7\x80\x89\x77\xfe\x16\xc2\x09\x7e\xd8\x83\xb8\x30\x83\xdd\x31\x29\x0c\xae\x95\x12\xc8\x24\x70\x99\xf3\x8c\x59\xb2\x7f\xbf\x46\x37\x3d\x67\x18\xe9\xe4\x94\x0e\x27\xec\xe1\x4e\x46\x23\xd4\xda\xab\x62\x67\x95\x70\xf2\x82\x24\x70\x72\x02\x92\x3b\xc1\x80\xbc\x60\xc2\x20\x95\x6e\x71\xc7\x34\xec\x86\x3c\x06\xf8\xe0\xec\x19\x9a\x98\xa8\xf5\x0a\xde\x60\xdc\x07\xf3\x99\x99\x9b\x31\x9c\x8a\x99\x1b\xaa\x97\xde\x03\x70\x7e\x70\x0e\xd1\x47\xe6\x31\x6e\x07\x11\xcf\x81\x4a\x2e\x1c\xcc\xfe\x11\xb5\x0e\x46\x96\x5d\x71\x59\x36\x82\xe9\x97\x11\xad\x3f\x3c\x27\x5a\xa5\x34\x52\x9a\xa9\xf9\xd1\x71\xee\x19\xbe\x6d\x7b\xfc\xc3\x94\xdb\x32\xfe\x1a\xd6\x0d\xa1\x6e\x11\x6f\xb0\xfe\xdb\xdc\x9b\x12\xb8\x4b\xbf\xc1\xf4\xab\x19\xb8\x95\x81\x17\x90\xf0\x52\xd9\x4f\x8a\xe5\xf8\xf4\xa8\x29\xd1\xba\x10\x72\xaa\x35\x9b\x66\x8b\x70\x57\x81\xf6\xa2\x35\xc2\x6d\x83\x7a\x33\x55\x7a\x6e\x77\xaa\x33\xe6\x25\xbe\xb6\xcc\x33\xcb\xbf\x56\x64\xe7\x9c\x6a\xec\x7e\x6c\x47\xb1\x55\x6a\xef\xe1\xb7\x0b\xdd\xe7\xe5\x51\x99\xbd\xd9\x57\x17\x79\x16\xff\x0b\x4a\x7c\x46\x8b\x87\x66\x5c\xda\x27\x6b\x9c\x69\x64\x16\xd3\xa6\xce\xe9\x55\x45\xdd\xac\xb4\x6f\x6f\xd7\xee\x7e\x41\xce\xc9\xe0\x5c\xe7\xbe\x55\x91\x6b\xc8\x46\x2f\x06\x0a\xc6\x05\xe6\x5b\xfb\xe9\x0a\xee\xb8\x12\x7e\x5f\x50\x85\xcf\xbf\xd2\x64\xcd\xbf\xd3\x1b\xc9\x6f\x1b\x94\x68\x4c\x4f\xa0\x5d\xd4\x13\x83\x2a\x53\x0e\x04\x5a\xdc\x6b\x56\xfb\x54\xfe\x16\x99\x76\x9c\xbc\x94\x4c\x53\xac\x7d\xa8\x03\xbf\x2a\x33\x90\xfa\xdf\xd2\x41\xdb\x07\xc4\x24\xdf\x34\x73\x1f\x6b\xfb\xe8\xfd\x08\x92\xb7\x14\xcd\xc6\xfd\x30\xc8\x13\x52\x8c\xac\xfd\x59\x99\x7f\x85\xbb\x3b\x81\x35\x1a\x47\xf6\xee\x98\x7f\x1d\x87\x77\x8c\x3d\x47\xe2\xb6\x4d\x0f\x00\x1f\x6a\x36\xbc\x18\x81\x28\xe2\xf8\x08\xa5\x50\xd7\x4c\xc0\x1a\x45\x8d\xda\x24\xe0\xfe\x4e\x32\xee\x6d\x7b\xd7\x36\xef\x64\x67\x65\x7b\x6a\x13\xdf\xb3\xc4\x2d\xfb\x3b\x8f\xbe\x46\xf7\x2f\x8a\x0e\xe4\xff\xc1\x25\x77\x1f\x2a\x8f\x36\xdc\xe4\xe2\xef\xc9\x57\xea\x22\xff\xa9\x7b\x83\x1b\x33\xf2\x81\x4a\x4e\x82\x94\xe7\x06\x0a\xad\x2a\x4f\x02\x6a\xc8\x8a\xd5\x7d\xbd\xe9\x40\x54\x91\xe0\x7b\xef\xa6\xeb\x7e\xf8\x16\x6c\xbb\x18\xbe\xff\x18\xa5\x54\x67\x43\x20\x2a\x76\x83\xd1\x4c\xb1\x82\xa3\x15\x08\x94\x51\x15\xc7\xc1\x82\x3e\x71\x3d\x58\xff\xc1\x55\x39\x7e\x18\x38\xa1\xef\x0c\x94\x79\x64\x56\xc0\xf3\x78\xbe\xa8\x98\x60\x1e\xee\xff\x02\x00\x00\xff\xff\xcb\x05\xd3\x14\xbe\x13\x00\x00") func templateBaseTmplBytes() ([]byte, error) { return bindataRead( @@ -135,12 +139,12 @@ func templateBaseTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/base.tmpl", size: 4838, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/base.tmpl", size: 5054, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateBuilderCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\xef\x6f\xdb\x36\x10\xfd\x2c\xfd\x15\x57\x41\x1d\x6c\x23\x96\xdb\x7e\x5b\x86\x0c\xe8\x92\x14\x30\x30\x64\x03\x92\x0c\x05\xd6\x61\x60\xa8\x93\x4d\x84\x26\x55\x92\x72\x13\x18\xfa\xdf\x87\x23\xa9\x5f\x4e\x5a\x24\xfb\x14\x46\x24\xdf\xdd\xbd\xf7\xee\xe8\xc3\x61\xb5\x48\xcf\x75\xfd\x68\xc4\x66\xeb\xe0\xc3\xbb\xf7\x3f\x2f\x6b\x83\x16\x95\x83\x4f\x8c\xe3\x9d\xd6\xf7\xb0\x56\xbc\x80\x8f\x52\x82\x3f\x64\x81\xf6\xcd\x1e\xcb\x22\xbd\xd9\x0a\x0b\x56\x37\x86\x23\x70\x5d\x22\x08\x0b\x52\x70\x54\x16\x4b\x68\x54\x89\x06\xdc\x16\xe1\x63\xcd\xf8\x16\xe1\x43\xf1\xae\xdb\x85\x4a\x37\xaa\x4c\x85\xf2\xfb\xbf\xaf\xcf\x2f\xaf\xae\x2f\xa1\x12\x12\x21\x7e\x33\x5a\x3b\x28\x85\x41\xee\xb4\x79\x04\x5d\x81\x1b\x05\x73\x06\xb1\x48\x17\xab\xb6\x4d\xd3\xc3\x01\x4a\xac\x84\x42\xc8\xb8\x41\xe6\x30\x83\xb6\xa5\xaf\x79\x7d\xbf\x81\xd3\x33\xb8\x63\x16\x21\x2f\xce\xb5\xaa\xc4\xa6\xf8\x93\xf1\x7b\xb6\x41\x88\x57\x1d\xee\x6a\xc9\x1c\x42\xb6\x45\x56\xa2\xc9\x20\x7f\xba\x25\x76\xb5\x36\x6e\xb4\x95\xdf\x35\x42\x52\x79\xa7\x67\x50\x1b\xa1\x1c\xcc\x6a\x66\x39\x93\x90\x17\x57\x6c\x87\x73\xc8\xce\xa7\xb9\x18\xe4\x28\xf6\xe1\x46\xbf\xee\x61\x08\x76\xb5\x82\x31\x72\xdb\x12\x9b\x44\x45\xf7\xa5\xd2\x06\x7c\x85\x42\x6d\x80\xf9\xc3\x3e\x18\x1d\x45\xe5\x84\x7b\x2c\x52\xf7\x58\xe3\x31\x8c\x75\xa6\xe1\x0e\x0e\x69\xc2\x3d\x05\x69\x72\x38\x2c\x41\x54\x90\x17\xeb\x8b\xe2\xd6\xa2\xb9\xf0\xfc\x95\x94\x46\x92\x78\xdc\xf5\x45\xf1\x5b\x40\xf8\x24\x50\xd2\x0e\x2c\xba\x8d\x1b\x8a\x41\x47\x09\x06\x55\x19\xd7\x60\x98\xda\x20\xe4\xff\x9e\x40\x5e\x51\x99\x79\xe1\xef\xda\x0e\x76\x09\x79\xf5\x3c\x6a\x35\xc6\x1c\x41\x2e\xc7\x98\x18\x30\x2f\xcb\x0d\x8e\x21\xf1\x09\xe4\x8e\xd5\x7f\x13\x2a\x7a\xd4\x51\xc6\xff\x04\x26\x0e\x43\x98\x65\xdb\xa6\x41\xd1\x6f\xc2\x6d\x01\x1f\x1c\x7d\xcd\x21\x8b\x98\xd9\x44\xa2\x64\x62\x0a\x8b\xce\xd1\x89\x22\x4a\x1c\xd3\x26\x1d\xaf\xd9\x1e\x83\x54\x18\x24\x9c\x68\x15\x1d\x5e\x32\xc7\xc8\x9a\x45\x5a\x35\x8a\xc3\x6c\xe2\x92\x8e\x99\x21\xfa\xdc\xa3\xce\xb8\x7b\x00\xae\x95\xc3\x07\x47\x8e\xa6\xbf\x73\x98\x2d\xc6\x01\x4e\x00\x8d\xd1\x66\x4e\x8a\xff\x48\x96\x65\x4f\xa2\xa8\x40\x1b\x92\xe1\x02\x2b\xd6\x48\x07\x33\xa5\x1d\xfd\xff\x47\xed\x84\x56\x4c\xce\xe3\xe1\x44\x54\x70\x94\x67\x11\x04\x3c\x16\xe1\xec\x0c\x94\x90\x94\x42\xe2\x2d\x45\x76\x1b\xf0\x23\x5a\x92\xec\x29\x23\x9f\xfc\xd0\x97\x11\x31\x9e\x8d\x45\x05\x88\x90\xe5\xda\xde\x88\x1d\x86\xd5\xed\xed\xfa\x02\xda\x76\x36\x1f\x19\x27\x86\x7c\x49\x96\xf0\xd3\xbe\xcb\x10\xa5\xc5\x21\x31\x83\xae\x31\x8a\x6a\x88\x74\xda\xe2\x0a\xbf\xcd\xb2\x6e\xae\xb4\xed\x29\xec\x84\xb5\xd4\x8b\x06\xbf\x36\xc2\x60\x09\x95\xc7\xfd\x92\x85\x60\x31\xf3\x2f\x59\x36\xef\x63\x44\xcf\x25\x49\x12\x5b\x6d\xf8\xd2\x99\x30\xd4\xf8\x17\x93\xa2\x64\x4e\x1b\x1b\xea\xbc\x54\xcd\xae\xbb\x4a\x53\x1b\x58\x59\x82\x6a\xa4\x64\x77\x12\x81\x6f\x91\xdf\x83\x56\xf2\xd1\x4f\x09\x1d\x65\x0b\x09\x59\x8f\xab\x1b\x47\x73\xd2\xd3\xbf\x67\xb2\x41\x58\xac\x06\x40\xc8\x7b\xac\xd3\x33\x60\xd4\x04\x83\xfa\xbd\x1d\xa2\x24\xf3\xe1\x5e\x98\x23\xfd\x5d\x72\xf7\x4b\x1d\xf2\x26\x3a\x04\xa6\xbc\x90\xc5\xd0\x98\xef\xfb\xa2\x67\x86\x64\x5f\xbc\x28\xd6\xfc\x17\x0f\xf9\x66\xec\xc9\x89\xc2\xd5\xce\x15\x97\xa4\x72\x35\x55\x78\xdf\xc7\xaa\x98\x90\xa4\x30\x2d\x9f\x57\xf9\x14\xde\xee\x33\x6f\x96\x20\xf7\x77\x19\x6a\x61\xec\xd5\x71\xf5\xd3\xf5\x0b\xa6\x1f\x41\x63\x71\xab\xc4\xd7\x06\x47\x2d\x2a\x51\x1d\x8f\x93\x22\x4c\xc4\x63\x62\xe0\x57\x78\x1f\x09\x79\x91\xe3\x1b\xe9\x44\x2d\x11\x98\xb5\x62\xa3\x76\xa8\x9c\x05\xad\x80\x41\x13\x72\xc0\x72\x83\x91\x1a\x3c\x6e\x80\x67\x1c\xef\x2b\xf0\xe6\xc2\xc1\x6d\x3f\x1e\x35\x4f\xe7\xfd\x64\xd4\xfc\xaf\xbe\x7d\x4d\xd6\xe3\x75\x0c\xf6\x5c\x9a\xc5\xb5\xd3\x26\xf8\xb6\x9b\xdb\xf3\x74\x78\x1d\x3e\x03\x67\x52\xda\xf0\x52\x50\xbb\xd5\x4c\x09\x6e\x89\x0e\xff\x29\x20\x5b\x60\x2a\x54\xf1\xaa\x47\xe2\xf3\xf3\xaf\xc4\xe4\x91\x20\xba\xf6\x27\xe3\x4e\x1b\x57\x30\xa4\xdc\xb5\xe3\xa8\x77\x7c\xaa\xb3\xe0\xf3\x81\x84\xfd\x2b\x1f\xd2\xdc\xed\x6a\xd9\xff\x7e\xaa\x20\x2b\x05\x93\xc8\xdd\xea\xad\x5d\x75\xbf\xe3\xc6\x2c\xfa\x4b\x0f\xfd\xf3\x1b\xae\x1f\xbf\xbd\xc3\xf2\xbf\x00\x00\x00\xff\xff\x0b\x99\x8d\xcd\xda\x0a\x00\x00") +var _templateBuilderCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x61\x6f\xdb\x36\x13\xfe\x2c\xfd\x8a\xab\xa0\x02\x52\xe0\xc8\x69\xbf\xbd\x09\xfc\x02\x5d\x9a\x6e\x06\xb6\x6e\x80\x93\xa2\x40\x5b\x14\x8c\x74\xb2\x09\x4b\xa4\x4a\x52\x6e\x02\x43\xff\x7d\x38\x52\xa2\x25\xd7\xd9\x96\x7e\x12\x25\xde\x3d\x77\xf7\xdc\xc3\xa3\xf6\xfb\xf9\x59\x78\x2d\x9b\x47\xc5\xd7\x1b\x03\xaf\x2f\x5e\xfd\xef\xbc\x51\xa8\x51\x18\x78\xc7\x72\xbc\x97\x72\x0b\x4b\x91\x67\xf0\xa6\xaa\xc0\x1a\x69\xa0\x7d\xb5\xc3\x22\x0b\x6f\x37\x5c\x83\x96\xad\xca\x11\x72\x59\x20\x70\x0d\x15\xcf\x51\x68\x2c\xa0\x15\x05\x2a\x30\x1b\x84\x37\x0d\xcb\x37\x08\xaf\xb3\x8b\x61\x17\x4a\xd9\x8a\x22\xe4\xc2\xee\xff\xbe\xbc\xbe\x79\xbf\xba\x81\x92\x57\x08\xfd\x37\x25\xa5\x81\x82\x2b\xcc\x8d\x54\x8f\x20\x4b\x30\xa3\x60\x46\x21\x66\xe1\xd9\xbc\xeb\xc2\x70\xbf\x87\x02\x4b\x2e\x10\xa2\x5c\x21\x33\x18\x41\xd7\xd1\xd7\xb8\xd9\xae\xe1\x72\x01\xf7\x4c\x23\xc4\xd9\xb5\x14\x25\x5f\x67\x7f\xb1\x7c\xcb\xd6\x08\xbd\xab\xc1\xba\xa9\x98\x41\x88\x36\xc8\x0a\x54\x11\xc4\x3f\x6e\xf1\xba\x91\xca\x0c\x5b\xee\x0d\x92\x30\xd8\xef\xcf\x41\x31\xb1\x46\x88\x1b\x66\x36\x14\x2c\xce\x56\xfc\xbe\xe2\x62\xbd\xb4\x56\x9a\x3c\x82\x20\xb2\xe9\x90\x49\xd7\x45\xce\x0f\x45\x41\x7b\xa9\x0d\x15\xdf\xb7\xbc\x22\xba\x2e\x17\xd0\x28\x2e\x0c\x24\x0d\xd3\x39\xab\x20\xce\xde\xb3\x1a\x53\x88\xae\xa7\xb5\x29\xcc\x91\xef\x9c\x87\x5f\x7b\x18\x4a\x73\x3e\x87\x31\x72\xd7\x51\x77\x88\xda\xe1\x4b\x29\x15\x58\xc6\xb8\x58\x03\xb3\xc6\x36\x18\x99\xa2\x30\xdc\x3c\x66\xa1\x79\x6c\xf0\x18\x46\x1b\xd5\xe6\x06\xf6\x61\x90\x5b\x4a\xc3\xa0\x6e\x0d\x33\x5c\x0a\x38\xdb\xef\x01\xe2\xec\x8f\xfe\xbd\x47\x0b\x83\x8d\x94\x5b\x0d\x9f\xbe\xfc\x26\xe5\x36\x74\xec\x7e\xe7\x66\x03\xf8\x60\x88\x87\x18\xa2\x5f\x1c\x7e\x34\xa9\x21\x98\x74\x41\xa3\x31\x64\x91\xf5\x1c\xf4\x0c\x52\xa1\x2b\xb6\x43\x57\x0b\xba\x1a\x27\xc5\xf4\x92\x2a\x98\x61\xa4\x85\x2c\x2c\x5b\x91\x43\x32\xa1\xb1\xeb\x6c\xf2\xa3\xe8\xa9\x45\x4d\x72\xf3\x00\xb9\x14\x06\x1f\x0c\x49\x88\x9e\x29\x24\x67\xe3\x00\x33\x40\xa5\xa4\x4a\x89\x12\x6a\x6d\xec\xf9\xf0\xed\x3c\x04\x8a\xb2\x61\x37\xea\x4b\xf4\x1a\xfa\x3a\x83\xb8\x74\x22\x7a\xc7\xb1\x2a\x7a\xf1\x90\x05\x2f\x41\x2a\x88\xcb\xec\x2d\x96\xac\xad\x0c\x24\x42\x1a\x7a\xff\xb3\x21\x28\x56\xa5\xce\x36\xe0\x25\x7c\x9d\x81\xdc\x12\x0c\xe5\xe8\x53\xe9\xba\x8c\xde\x4b\xdf\x9c\x5f\xd1\x40\xd7\x25\xe9\x15\xbc\x90\x5b\x4a\x3d\xf0\xa1\x46\x71\x1c\x6a\x10\xec\x06\xc0\xd1\x01\xea\x01\x7b\xd3\x9e\x8c\xfd\xfe\x90\xec\x52\xdf\xf2\x1a\xdd\xea\xee\x6e\xf9\xd6\xc6\x3b\x74\x2e\x70\x21\xa7\x49\xae\xd0\x38\xd8\x95\x95\x99\x25\x82\xfc\x76\xa9\xcf\x10\x2b\x8d\xde\x5f\xa1\x69\x95\x00\xc1\xab\xbe\x0d\x3a\x7b\x8f\xdf\x93\x68\x18\x00\x5d\x77\x09\x35\xd7\x9a\x44\xae\xf0\x5b\xcb\x15\x16\x50\x5a\xd4\xcf\x91\x8b\xd4\x67\xfe\x39\x8a\x46\x31\x7c\x8a\x43\x0b\xfc\x17\x7a\xb1\xea\x75\x45\x7e\x60\x15\x2f\x98\x91\x4a\xbb\x42\x6f\x44\x5b\x1f\x9a\xb1\x7b\x6e\x33\x7c\x2f\x78\x49\xf5\x3c\x4d\xbb\x8f\xeb\xd8\xb9\xb2\xd6\x2f\x16\xc4\x44\x8f\x30\xe1\xa6\xac\x4d\x76\x43\xfc\x94\x53\x6e\x76\x1e\xa6\x64\xbc\x22\x6e\x68\x79\x9a\x9f\x4b\x78\xb9\x8b\x2c\xcd\x8e\xa8\x93\xfc\x1c\xaf\x47\xe2\x46\x27\xee\x9b\x62\x8d\x53\x6d\x5b\x31\xa3\x17\x73\x4f\xdf\xa0\x46\xcc\xee\x04\xff\xd6\xfa\x9e\xff\x9b\xc6\xf1\x48\x3b\xcb\xb7\x13\x95\x1f\x4b\x88\x97\x50\xa1\x48\xfe\x1b\x92\x4e\xd2\x14\x16\x0b\xb8\x18\x61\x1d\xd4\xfc\x53\x62\xc4\x62\x8d\x3d\xd7\x78\xac\xc5\x7f\x22\x77\xc7\x14\x5d\x42\x01\xf5\xdd\x06\x0b\x83\x40\xd0\x2d\x3c\x19\x4e\x61\x90\x86\xe3\x12\x47\x13\x2f\xb3\x63\x79\x54\x0e\x79\xdb\xc4\xc1\x11\x3b\xb6\xb5\x98\x2b\x23\x95\x13\xe1\x30\x1b\xd3\x30\xe8\x1c\x9b\x04\x40\x29\xd5\xad\x01\x2b\x6b\x49\x30\x76\x85\xef\x5a\x91\x27\x34\x75\x4f\x8d\xd3\x19\xd4\x30\x9c\x83\x14\x92\x0f\xac\x6a\x71\x3c\x52\x03\x7f\xbf\x0c\x4d\xaf\xb3\x7e\x00\x1f\x5d\x34\x69\x7f\xe8\x0e\x03\xed\xa9\x13\xd0\x0a\x7c\x68\x30\x37\x58\x80\xef\xb9\xbd\xeb\x5e\xde\x46\x33\xa8\x3d\xf7\xc7\xe3\x09\x16\xde\x9e\x76\x7f\x8e\xb0\x43\x5a\x83\x7b\x18\x04\x36\x79\x3a\x7b\x9c\x2a\x7c\xba\x5b\x57\xc0\xe1\xff\x70\x71\x05\xfc\xfc\xdc\xb3\x73\x22\xbc\xb5\xfe\xc4\xcf\x5f\x7d\x49\xea\xd6\x10\x38\xd5\xe3\x8e\x4e\x3f\x57\xea\xd6\x38\x06\x6d\x62\xb3\xe3\xb3\x74\x62\xa4\x1c\xe9\xdb\x81\x76\xe1\x8f\xf5\x1c\xae\xe5\x8f\x90\xb3\xaa\xd2\xee\x8a\x66\xa2\x80\x86\x09\x9e\x6b\x3a\xd8\xf6\x93\x73\xd5\xc0\x84\x6b\xf9\xb3\x6e\xe7\x8f\xa7\xaf\xe7\xc9\x01\xa0\xcc\x77\xb3\xf1\x2c\x1d\xd3\x34\x6a\x4b\x3f\x70\x47\xf5\xda\x54\x13\x37\xee\x0e\x55\xee\x9e\xf9\x07\x13\x9b\xba\xa9\xfc\xaf\x40\x09\x51\xc1\x59\x85\xb9\x99\xbf\xd4\xf3\xe1\x8f\x75\xac\x14\xeb\xf4\xe0\xff\x7b\x9c\xfb\xf1\x4f\x8f\x5f\xfe\x1d\x00\x00\xff\xff\x9b\x57\xcc\xea\xc3\x0b\x00\x00") func templateBuilderCreateTmplBytes() ([]byte, error) { return bindataRead( @@ -155,12 +159,12 @@ func templateBuilderCreateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/create.tmpl", size: 2778, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/create.tmpl", size: 3011, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateBuilderDeleteTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x55\xc1\x6e\xe3\x36\x10\x3d\x8b\x5f\xf1\x2a\xb8\x85\xbd\x48\xe9\x74\x6f\x0d\xe0\xc3\x36\xcd\x02\x0b\x2c\xd2\xa2\x5b\xa0\x01\x8a\x1e\x68\x72\x64\x11\x91\x49\x95\xa4\x62\x1b\x86\xfe\xbd\xa0\x68\xc9\x52\xe2\xec\xe6\xd0\x93\x2d\x0d\xe7\xcd\x9b\xe1\x7b\xa3\xe3\x71\xf9\x8e\xdd\xda\xfa\xe0\xf4\xa6\x0c\x78\x7f\xfd\xd3\xcf\x3f\xd6\x8e\x3c\x99\x80\x8f\x42\xd2\xda\xda\x47\x7c\x32\x92\xe3\x43\x55\xa1\x3b\xe4\x11\xe3\xee\x89\x14\x67\x7f\x96\xda\xc3\xdb\xc6\x49\x82\xb4\x8a\xa0\x3d\x2a\x2d\xc9\x78\x52\x68\x8c\x22\x87\x50\x12\x3e\xd4\x42\x96\x84\xf7\xfc\xba\x8f\xa2\xb0\x8d\x51\x4c\x9b\x2e\xfe\xf9\xd3\xed\xdd\xfd\x97\x3b\x14\xba\x22\x9c\xde\x39\x6b\x03\x94\x76\x24\x83\x75\x07\xd8\x02\x61\x54\x2c\x38\x22\xce\xde\x2d\xdb\x96\xb1\xe3\x11\x8a\x0a\x6d\x08\xb9\xa2\x8a\x02\xe5\x68\xdb\xf8\x76\x56\x3f\x6e\x70\xb3\xc2\x5a\x78\xc2\x8c\xdf\x5a\x53\xe8\x0d\xff\x5d\xc8\x47\xb1\x21\x9c\x52\x03\x6d\xeb\x4a\x04\x42\x5e\x92\x50\xe4\x72\xcc\x5e\x86\xf4\xb6\xb6\x2e\x8c\x42\xb3\x75\xa3\xab\xd8\xde\xcd\x0a\xb5\xd3\x26\x60\x5e\x0b\x2f\x45\x85\x19\xbf\x17\x5b\x5a\x20\xff\x75\xca\xc5\x91\x24\xfd\x94\x32\x86\xff\x03\x4c\xdb\xb2\xe5\x12\x63\xe0\xb6\x8d\xc3\x8c\x93\xe8\xdf\x14\xd6\xa1\x6b\x50\x9b\x0d\x44\x3c\x3c\x29\x19\x33\xc8\x04\x1d\x0e\x9c\x85\x43\x4d\xcf\xd1\x7c\x70\x8d\x0c\x38\xb2\x4c\x76\x83\x60\x59\xed\x48\x69\x29\x02\x79\xfc\xfd\xcf\xf0\xc0\x63\x5e\x8f\xc8\x5a\xc6\x22\xb3\xbf\x4a\x72\x04\xa1\x94\x87\x80\xa1\x1d\x86\xe3\x08\xb6\x63\x99\x46\xdf\x93\xe5\xac\x68\x8c\xc4\x7c\xdc\x79\xdb\xe2\xdd\x94\xd3\x22\xe1\xce\x6b\x0f\xce\xf9\x65\x06\x8b\xe7\x49\xb1\x83\x29\x2c\x1f\x35\xb2\x82\xa8\x6b\x32\x6a\xfe\xea\x91\x2b\xd4\x9e\x73\xbe\x60\x99\xa3\xd0\x38\x83\xc9\xed\xa4\x96\x97\x4b\xdc\xed\x49\x82\xf6\x24\x9b\x08\x3b\x74\xa8\xad\xc1\xbf\x0d\xb9\x03\x84\x51\x48\x08\x1e\xa5\xdd\x61\x2b\xcc\x01\x4f\xe4\x82\x96\xe4\xb1\x8b\xf3\x4a\x33\x51\x6f\x1d\x46\x2c\x39\x97\x61\x0f\x69\x4d\xa0\x7d\x88\x8a\x8d\xbf\x0b\xcc\xb5\x09\x57\x20\xe7\xac\x5b\xc4\xfe\x2f\x33\x4f\x73\xfb\x12\xac\x4b\xfa\xee\xf1\x16\xa3\x96\x1e\x92\x45\x1f\xa9\x7b\xba\xc2\xba\x09\xa8\x85\xd1\xd2\x43\x17\x10\x26\x15\x81\x95\xb2\x71\xfe\x12\x71\xbc\xc6\xfc\xe1\x32\xf5\xe8\x8d\x23\xcb\x4c\x47\x3f\x8a\xff\x39\xe9\x33\xcb\x4c\x17\xdd\xa1\xef\x56\x30\xba\x8a\x59\x59\x47\x6d\x4e\xce\x2d\x58\xd6\x0e\x7d\x1b\x96\x5c\xb8\xd3\xa1\x04\xed\x03\x19\x85\x19\xf2\x5f\x12\xa3\x7c\x62\xab\x4e\x2b\x61\x5b\x57\x83\x55\x0b\xe4\x4a\x8b\x8a\x64\x58\x7e\xef\x97\xfd\xca\x18\x0f\xae\x4b\xda\x0f\xf6\x4f\xe9\xfc\xe4\xe4\x58\xac\xdf\x02\xd6\xd0\x8b\x45\x30\x14\xcf\x7f\x33\x67\xfb\x5b\x43\x7f\x5c\xdc\x00\x23\x88\x36\x5d\xd3\x33\xe0\x6f\x2e\x02\xaf\xcd\xa6\x4a\x76\x7f\x7d\x11\x4c\x01\xcf\xbb\xe0\x1b\x57\xfb\x46\x33\x8c\x85\x32\xee\xb4\x07\x9c\x54\xff\x9a\xd0\x93\xfa\x5e\xe8\x65\x8a\xc9\xbf\x22\x21\xbf\xd3\x41\x96\xdd\x96\x8b\x5b\xff\x2c\xa7\x1b\x96\xf5\xf2\x21\xe7\x4e\x61\x83\xd5\x0a\xd7\xa3\xd0\x0f\xf7\x36\x7c\x8c\x9f\xa6\xbb\x48\xe4\x98\x86\x7a\xfe\x62\xf0\xcf\x62\x4d\x55\xcb\x32\x45\x85\x68\xaa\x30\xca\x34\xba\x8a\x12\xfd\x1f\x9c\xf6\xc6\x01\xbe\xe2\xb7\xd3\x9d\xbe\x61\x62\x0f\xc3\x6e\x38\xab\xfa\xbf\x00\x00\x00\xff\xff\x9c\x31\x5b\x63\x10\x08\x00\x00") +var _templateBuilderDeleteTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x56\x71\x6f\xdb\xb6\x13\xfd\x5b\xfc\x14\xaf\x82\xfb\x83\x54\x38\x74\xda\xff\x7e\x29\x3c\xa0\xeb\x52\xac\x40\xd7\x0d\x6b\xb1\x15\x28\x82\x81\xa1\x4e\x36\x61\x89\xd4\x28\x2a\xb1\x61\xe8\xbb\x0f\x24\x6d\x59\x76\x9c\x36\x18\x16\x04\x89\x44\xde\x3d\xde\x7b\x77\xc7\xd3\x76\x3b\x7b\xc1\xde\x9a\x66\x63\xd5\x62\xe9\xf0\xea\xf2\xe5\xff\x2f\x1a\x4b\x2d\x69\x87\x77\x42\xd2\xad\x31\x2b\xbc\xd7\x92\xe3\x4d\x55\x21\x18\xb5\xf0\xfb\xf6\x8e\x0a\xce\x3e\x2f\x55\x8b\xd6\x74\x56\x12\xa4\x29\x08\xaa\x45\xa5\x24\xe9\x96\x0a\x74\xba\x20\x0b\xb7\x24\xbc\x69\x84\x5c\x12\x5e\xf1\xcb\xfd\x2e\x4a\xd3\xe9\x82\x29\x1d\xf6\x3f\xbc\x7f\x7b\xfd\xf1\xd3\x35\x4a\x55\x11\x76\x6b\xd6\x18\x87\x42\x59\x92\xce\xd8\x0d\x4c\x09\x37\x3a\xcc\x59\x22\xce\x5e\xcc\xfa\x9e\xb1\xed\x16\x05\x95\x4a\x13\xd2\x82\x2a\x72\x94\xa2\xef\xfd\xea\xa4\x59\x2d\x70\x35\xc7\xad\x68\x09\x13\xfe\xd6\xe8\x52\x2d\xf8\x6f\x42\xae\xc4\x82\xb0\x73\x75\x54\x37\x95\x70\x84\x74\x49\xa2\x20\x9b\x62\xf2\x70\x4b\xd5\x8d\xb1\x6e\xbf\x15\xdf\x90\xb1\x24\xf5\xa7\x3c\x04\x9e\x85\xe5\xc3\x7b\xca\x72\x16\x10\x27\xb7\x9d\xaa\xbc\x2a\x57\x73\x34\x56\x69\x87\xac\x11\xad\x14\x15\x26\xfc\xa3\xa8\x29\x47\xfa\xd3\x31\x05\x4b\x92\xd4\x5d\xf4\x18\x9e\x07\x98\x9d\x51\xdd\x39\xe1\x94\xd1\x07\xd8\x83\x5f\xca\xf7\xbb\x01\x93\xcd\x66\x18\x07\xd2\xf7\x3e\x67\x5e\xf0\xfd\x4a\x69\x2c\x82\x8e\x4a\x2f\x20\xbc\xf1\x51\x88\xde\x83\xb4\x53\x6e\xc3\x99\xdb\x34\x74\x8a\xd6\x3a\xdb\x49\x87\x2d\x4b\x64\x90\x85\x25\x4b\x63\x56\x2d\xc2\xcf\xd7\x9b\x9f\x8d\x59\xb1\x64\x08\x18\x78\x11\xb4\xfa\x65\xb7\xb0\x3b\x81\x25\x8d\xa5\x42\x49\xe1\xa8\xc5\xd7\x9b\xe1\x85\x07\xe3\xbd\x51\xcf\x02\x9d\x3f\x97\x64\x09\xa2\x28\x5a\x08\x68\xba\xc7\x60\x0e\x67\x02\xb5\x58\x16\x7b\x86\x9c\x95\x9d\x96\xc8\x8e\xe4\xed\xfb\x18\xc9\x81\x49\x1e\x81\xb3\xa6\x05\xe7\xfc\x7c\x08\xf9\xa9\x93\xe7\x3d\xc6\xed\x7b\x3e\x62\x32\x87\x68\x1a\xd2\x45\xf6\xa8\xc9\x14\x4d\xcb\x39\xcf\x59\x62\xc9\x75\x56\xe3\x24\x48\x16\x33\x78\xbd\x26\x09\x5a\x93\xec\x3c\xec\x40\xd1\x2b\xfa\x77\x47\x76\x03\xa1\x0b\x44\x84\x16\x4b\x73\x8f\x5a\xe8\x0d\xee\xc8\x3a\x25\xa9\xc5\xbd\x17\x2c\x8a\x52\x9c\x53\xe3\x9c\x18\xfe\xc8\x4c\xba\x35\xa4\xd1\x8e\xd6\xce\x57\xbd\xff\x9f\x23\x53\xda\x4d\x41\xd6\x1a\x9b\x7b\xfe\x77\xc2\xfa\xde\x48\xc8\xda\xb8\xca\x92\x44\x94\x25\x49\x47\x05\x94\x76\x2c\xc9\x59\xa2\x4a\x54\xa4\x4f\x73\xc0\x43\xad\xe4\x98\xcf\x71\xe9\xa1\x06\xbf\x80\x8f\xf9\xa9\x1c\x31\x19\x9f\x9c\xb1\xb1\xd1\xf6\x41\xe6\x2c\xe9\x41\x55\x4b\x01\xc4\x07\x54\x77\x0e\xa1\xc8\x8c\x87\x09\x4f\xf4\xae\xd3\x32\xf3\xec\xcf\xf1\x9a\xa2\xc6\xbe\x2a\x73\x64\x7f\x88\xaa\xa3\x31\xcb\x64\x28\xe2\x29\xcc\xca\x77\x5e\xcd\xb3\xb3\xc5\x9c\x7b\x63\x55\xe2\x99\x59\x45\xc7\x7d\x6e\xb5\xaa\xa6\x28\x6b\xc7\xaf\x3d\x6a\x99\xa5\x9d\xa6\x75\x13\x75\x1a\x3a\x24\xf4\xd8\xf3\xcf\xe9\x14\x75\x00\xea\xfd\x9f\xa3\xa6\xef\x7b\xcc\x07\x7b\xbf\xfb\xef\x45\x1b\x42\x3b\x82\x60\x49\x12\x48\xf8\x9b\x41\x79\xa6\x8f\x67\xee\x35\x14\x7e\xc0\xe5\x6b\xa8\x8b\x8b\x41\xa5\x33\x21\x04\xeb\xaf\xea\xe2\xe5\x4d\x56\x77\xce\x83\x7b\x5e\xaa\xc4\x5f\x31\xe8\xab\xc0\x28\x2a\x49\x3e\xb8\x29\x4e\x38\xe7\xaf\x83\xe1\xb3\xb9\x97\x31\x1e\xb5\x8b\xfd\x72\x08\x9a\xf9\xdf\xb3\x8c\x0e\x6d\xf4\x25\xce\xac\x15\x85\xb7\x29\x6e\x3b\x87\x46\x68\x25\x5b\xa8\x12\x42\xc7\x94\xc3\x48\xd9\xd9\xf6\xc9\x57\x47\x40\x3e\xdf\x2e\xfe\x7a\xde\xb2\x44\x0f\x44\x4f\xb5\x19\xe5\x43\x95\xa7\x24\x43\x68\x19\x59\x9b\x8f\xc9\x69\x16\x27\xd6\xbd\x72\x4b\xd0\xda\x91\x2e\x30\x41\xfa\x63\x8c\x28\x3d\x1a\x18\xa1\x78\x5c\xdd\x54\xc3\xb4\x28\x91\x16\x4a\x54\x24\xdd\xec\x79\x3b\xdb\xcf\xd0\x71\x89\x04\xa7\xf5\x30\x0f\xa3\x3b\xdf\x8d\x1f\x7f\xd8\x6e\x62\x4e\x8c\xa6\x07\x23\x6e\x38\x3c\xfd\x55\x1f\x06\x9b\xd1\xf4\xfb\xd9\xd9\x36\x82\x18\xcd\xab\xa3\xd5\xef\x8c\xac\x56\xe9\x45\x15\x07\xd3\xe3\x23\xeb\x18\xf0\x30\xb5\xbe\x93\xda\x27\x5e\xc0\xe3\x42\x19\x33\xdd\x03\x1e\x9d\xfe\xad\xcb\x35\x56\xdf\x83\x7a\x39\xc6\xe4\xdf\x28\xa1\xf6\x5e\x39\xb9\x0c\xf3\xd8\x7f\x06\x1d\xca\xe9\x8a\x0d\x1d\x13\xda\x25\x6c\xeb\x70\xf5\x8e\xb6\xfe\xf7\xd1\xb8\x77\xfe\x5b\x2d\xdc\x51\x5b\x9c\x7c\xd9\xf0\x0f\xe2\x96\xaa\x9e\x25\x05\x95\xa2\xab\xdc\xc8\x53\xab\xca\x97\xe8\x7f\xd0\x69\x4f\x14\xf0\x91\x7e\xdb\xe5\xf4\x09\x8a\x7d\x89\x92\xc5\x52\xde\x55\xf5\x3f\x01\x00\x00\xff\xff\xda\x21\xa0\xc6\x21\x0b\x00\x00") func templateBuilderDeleteTmplBytes() ([]byte, error) { return bindataRead( @@ -175,12 +179,32 @@ func templateBuilderDeleteTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/delete.tmpl", size: 2064, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/delete.tmpl", size: 2849, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateBuilderQueryTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x6d\x8f\xdb\x36\xf2\x7f\x6d\x7f\x8a\xa9\xb1\x5d\xd8\x81\x23\x27\x79\xf7\xdf\x3f\xf6\x80\x6d\x36\x39\x18\x28\xd2\x6b\x12\xa0\x05\x82\xa0\xe5\x4a\x23\x9b\x8d\x4c\xaa\x24\xe5\xdd\x85\xcf\xdf\xfd\xc0\x21\x25\x51\x0f\x5e\xcb\xbb\x7b\xbd\xbe\xb2\x25\x0d\x87\x9c\x99\xdf\xfc\x86\x4f\xbb\xdd\xe2\xc5\xf8\xad\xcc\xef\x15\x5f\xad\x0d\xbc\x79\xf5\xfa\xff\x5e\xe6\x0a\x35\x0a\x03\xef\x59\x8c\x37\x52\x7e\x83\xa5\x88\x23\xb8\xca\x32\x20\x21\x0d\xf6\xbb\xda\x62\x12\x8d\x3f\xaf\xb9\x06\x2d\x0b\x15\x23\xc4\x32\x41\xe0\x1a\x32\x1e\xa3\xd0\x98\x40\x21\x12\x54\x60\xd6\x08\x57\x39\x8b\xd7\x08\x6f\xa2\x57\xe5\x57\x48\x65\x21\x92\x31\x17\xf4\xfd\xc7\xe5\xdb\x77\x1f\x3e\xbd\x83\x94\x67\x08\xfe\x9d\x92\xd2\x40\xc2\x15\xc6\x46\xaa\x7b\x90\x29\x98\xa0\x33\xa3\x10\xa3\xf1\x8b\xc5\x7e\x3f\x1e\xef\x76\x90\x60\xca\x05\xc2\xe4\xcf\x02\xd5\xfd\x04\xf6\x7b\xfb\xf2\x2c\xff\xb6\x82\x8b\x4b\xb8\x61\x1a\xe1\x2c\x7a\x2b\x45\xca\x57\xd1\xbf\x58\xfc\x8d\xad\x10\x7c\x4b\x83\x9b\x3c\x63\x06\x61\xb2\x46\x96\xa0\x9a\xc0\x59\xf7\x13\xdf\xe4\x52\x99\xe0\xd3\xd9\x4d\xc1\x33\x6b\xdd\xc5\x25\x9c\x45\x3f\xdb\x5e\x3f\xb0\x0d\x96\x1d\x2b\x8c\x91\x6f\xdd\xe7\xea\x7f\xd5\xc6\xea\x58\x2c\x20\x54\xb3\xdf\x5b\xcf\x59\xb3\xcb\x37\xa9\x54\x40\xd6\x70\xb1\xb2\xa2\x39\xd3\x31\xcb\xe0\x2c\xf2\xfd\x00\x0a\xc3\x0d\x47\x1d\x8d\xcd\x7d\x8e\x6d\x6d\xda\xa8\x22\x36\xb0\x1b\x8f\x62\x32\x7b\x3c\xca\xf8\x86\x9b\xd1\xe8\x05\x17\x66\x3c\x92\x69\xaa\xb1\x7e\x52\x09\xaa\xd1\xe8\xcb\xd7\x9f\xec\x9f\xf1\xa8\x10\xfc\xcf\x02\xed\x0b\x6d\x14\x17\xab\xf1\x28\x57\x98\xf0\x98\x19\xd4\x30\xfa\xf2\xb5\x7a\x8a\x6c\xaf\xe5\x88\xc6\xa3\xdd\xee\x25\xdc\x72\xb3\x86\xb3\xe8\x5d\xb2\x42\x4d\x2f\x47\x8b\x05\x20\x5b\xa1\x7a\x99\x49\x96\x58\x6b\xd0\x7e\x8b\xc6\x23\x92\x57\x4c\xac\x10\xce\xd0\xba\x2a\x72\x0d\x46\x56\x47\x60\x32\x56\x36\xbf\xb0\xfd\x61\xf4\xf9\x3e\xc7\xa6\xd3\x9d\x2e\x14\x49\x35\x8e\xf0\xff\xe2\x05\x5c\x25\x09\x37\x5c\x0a\x96\x41\xca\x31\x4b\x34\x18\x09\x2c\x49\xec\x4f\xe0\xf6\x08\x08\x52\xd4\xea\xcc\x6c\xf2\xcc\x0e\x2b\x57\x5c\x98\x14\x26\x09\x67\x19\xc6\x66\xf1\xbd\x5e\x50\x64\x16\x4e\xd3\x04\xce\xa2\x4f\x46\x2a\x0f\x2a\x6a\xcb\x53\x58\x33\xfd\xb9\x04\x90\x53\x55\x8d\xf3\xce\x34\x3f\x44\x9d\x51\x2f\x16\xc0\x85\x41\xb5\xc1\x84\x5b\x39\xea\x2f\xb2\x32\x8d\xce\x20\x7c\x8e\x7e\xa8\xf1\xe5\x10\xf6\xcb\x1a\x15\x5a\x2b\x35\x30\x10\x78\x0b\x55\xe0\x08\x5e\xa1\xdd\xe3\xb4\x10\x31\x4c\x1b\xe0\x2d\x1d\x5e\xc3\x6a\xe6\x54\x4e\x73\x0d\x51\x14\xf5\xc3\x60\xd6\x6e\x64\x41\x18\xea\xdd\xef\xa3\x00\x4e\x97\xc0\xf2\x1c\x45\xd2\xee\x3a\x90\x99\x43\xae\xa3\x28\x9a\x8d\x47\x0a\x4d\xa1\x04\xb4\x44\xbd\xb5\x3f\x5a\x80\x97\xd6\x12\xda\x41\x1b\xcc\xcb\x08\x7b\x17\x0e\xb4\x93\x94\x4d\x9d\x16\x2e\xcc\x51\xa3\xec\x88\x9d\xf4\x25\x9c\xd3\x9f\x23\xa3\xfd\x89\x32\xd0\x0f\x57\x80\x4b\xc8\x27\x0c\xd8\xe9\x9b\x7a\x3d\x43\x87\xec\xc5\x2f\xe1\xdc\xfd\x3b\x36\x68\xcb\x0f\xf5\x98\xe9\xe9\x09\x43\xb6\xed\xa7\xd2\x42\x89\xfe\x0e\x1b\x31\x75\x7a\x10\x35\xf4\x79\x0e\xf2\x18\x5e\x6c\xdd\x73\x05\x85\xca\xd6\x9a\x69\xd0\x7c\xc3\x33\xa6\xb8\xb9\x77\x24\x66\x69\x8a\x2c\xe2\xa8\x6d\x51\x8a\x33\x8e\xc2\x44\x94\xb1\xc4\x12\xbb\x5d\xc9\x5e\xbf\xcd\x3d\x83\x85\xc4\x47\x5c\x95\xac\xf0\xb7\xa0\x56\x10\x95\xc0\xb4\x66\x36\xa2\x32\x9b\x39\x33\x98\xfc\x5c\x15\x2f\x9b\xff\xf4\xd4\xcb\x82\xf1\x9a\x71\xe1\xaa\x45\x5c\x28\x65\x4b\x35\x39\x1e\xa4\xab\x9c\x8e\x24\xab\x3a\x91\xac\x30\x1a\x8f\x06\xc6\xe4\x60\xaf\x53\x1f\x9d\x86\x45\x2e\x44\x23\xd7\xfb\xc5\x25\x9c\xf7\x48\xec\x5c\x01\xba\x68\x47\x21\x72\xef\x4b\x4e\x74\x2e\xbf\x33\x96\x01\xcf\x60\xf2\xd1\x0b\x4e\x82\x36\x13\xeb\xdb\x89\xf5\xf4\x4b\x57\x27\xac\xc6\xa3\x24\x9d\x33\xb3\x6e\x53\xf4\x43\x34\x5c\xf1\xb0\xeb\xc4\x43\x88\x74\x8d\x47\x14\x74\x4f\xd2\x36\x21\xde\x73\xa5\x0d\x38\x19\x17\x91\x94\xde\x84\x84\xe8\x2a\xf5\x7d\x39\xaf\x71\x39\x02\x1f\x7d\x9b\x17\x1f\xa4\x79\x6f\xe7\x42\xef\x94\x92\x0a\x6e\xd7\x28\x40\x48\xab\x20\x93\xb7\x76\xd6\x50\xa9\xb9\x65\xda\xcd\x9a\x06\x27\x18\x8d\x6e\x1a\x9b\x3b\x88\xa5\x30\x78\x67\xec\x1c\xc8\xfe\xce\x60\xfa\x22\x1c\xe2\x1c\xd0\xf6\x3e\xf3\x09\x97\x67\x85\xa2\xb9\xc6\xc7\x5a\x3b\x89\x58\x47\xb7\xc3\xe8\x98\xf2\xf5\x2c\xba\xca\x32\xdb\xd7\x6c\x3c\xe2\x29\x09\x7f\x77\x09\x82\x67\x84\x10\xef\x45\xc1\x33\xd2\x63\x1d\x69\xa5\x32\x14\xd3\x03\xfd\xcd\xe0\xf2\x12\x5e\x75\x1a\x9f\x37\xdc\xb5\x73\x8e\xae\xa7\x74\xd1\x8f\xec\x06\xb3\x3d\xe9\xaf\x93\xbf\x4f\xff\x97\x57\x5f\xe7\x56\xe5\x38\x08\xe4\xaf\x6e\xfa\xfa\x0d\xdd\xe3\x1c\x6e\x0a\x03\x39\x13\x3c\xd6\xb6\xa2\x33\xe1\xdc\x04\x32\x8e\x0b\xa5\x4f\x0b\xc3\xaf\xfd\x71\x68\x84\xa1\xe4\xbb\x41\x7e\xaf\x82\xdb\x71\xf8\xf9\x39\x7c\xb7\xd4\xa5\xa3\xa6\xa8\x5c\x60\x47\x64\x09\x3d\xb6\xfc\xd3\xe8\x30\x74\xc8\xf2\xfa\x18\xb6\x79\x72\x1a\xae\x79\xf2\x58\x1c\x2f\xaf\x0f\x20\x99\x27\x6e\x48\xcb\x6b\x62\xd3\xca\x67\x35\xa4\xb7\x4c\x01\x4f\x34\x7c\xf9\xda\x12\x24\xcf\xf1\x44\xbb\x06\x0f\x60\x7b\x79\xad\xc9\xd5\xff\xdf\x0f\xec\x10\xcf\x3c\xd1\x01\x76\x9d\xde\xa1\xa8\x0d\xd5\xf9\xf0\xf0\x44\xf7\x42\x75\x79\xdd\x04\xeb\xf2\xfa\x79\xe1\x7a\xc8\xdd\x2d\x0f\x5a\x23\x79\xf2\x30\x48\x9d\xaa\x27\xc2\x94\x27\xe5\x1c\x44\x64\xf7\x0d\x54\x4a\xfb\xe2\x18\xe1\xce\xab\x26\x95\x5b\x78\x0a\x42\x1a\xc0\x3b\x16\x9b\xcc\x16\x4f\x2c\x1b\x5a\x84\x3a\x71\x1c\x0e\x52\x3b\xae\xbf\x86\x6b\xdf\x9c\xce\xb5\xfa\x96\x9b\x78\xfd\x30\xdf\xda\xb5\xa2\x5d\x29\xbf\xbe\xa8\x95\x1c\x23\x4f\xd7\xe2\xd5\xc5\x23\x59\x3a\xc1\x94\x15\x99\xe9\x6b\xfe\x89\x8b\x55\x91\x31\x75\x94\xe7\x6b\x54\xd4\xf4\x6d\x9f\x9e\x2b\x1d\x48\xf3\x73\x93\x77\x09\x96\xde\x00\x9e\xc4\xd3\x56\x53\x8b\xa6\xbb\x09\xd1\x62\xe9\x61\xc9\xe0\xa9\xfa\x51\x89\xf0\xbf\x23\xeb\x37\xc3\xc8\x3a\x48\x08\x22\xec\x06\xf8\x79\x02\x97\x9e\x78\x43\x84\x9f\xc6\xe5\x01\xb6\xeb\x86\x83\x51\x5d\x8e\x35\x40\x77\xc0\xf8\xce\xc5\xcf\x8a\xf0\xe7\xe1\xfb\x3a\xf6\x27\x20\xbb\xa2\xf6\xab\x2c\x03\xbc\xc3\xb8\x30\xa8\x6b\xb4\x02\x13\x49\x0d\x58\xc8\xb8\x36\x20\xd3\x06\x35\x79\x9c\x0f\xb6\xd8\xd3\x67\x0f\x3e\xbf\x7c\x3d\x48\xd6\xfd\x8b\xc9\xa8\xb5\x25\x53\x31\x73\x65\x52\x4d\x4b\x57\x59\xf6\x5c\x31\xb3\x7a\xfb\x4d\x68\x59\xf0\x98\x32\xf3\x50\x75\x39\x48\x4e\x7d\x3d\x78\x27\x2c\xaf\xf5\x49\x71\x0d\x89\x6b\xb8\x4b\x7c\xda\xf7\x06\xb5\x8f\x73\x06\xf1\xcd\x01\x0f\x7d\x42\xbb\xc8\x9c\xb6\xf3\xf7\x3d\xc7\x2c\x59\x5e\xcf\xa2\x4f\x31\x13\x76\x30\x73\x38\xb7\xf4\x72\x80\x89\x9a\x35\xba\x9e\xf0\x85\xb3\xbd\xe5\xb5\xae\x01\xb4\xbc\xd6\xcf\x05\x20\xab\xf7\x10\x80\x7a\x73\x5e\x1f\x84\x4b\xc9\xb7\xa7\x64\xbc\xf6\xe6\xbd\x95\x85\x68\x2e\xa0\x63\x7a\x43\xdb\xfd\x08\x2b\xbe\x45\x71\xe2\xb6\x12\xa9\x3c\x54\x7e\x84\x39\x3d\xa5\x2b\x85\xb3\x70\xd0\x75\x54\xe8\xf1\xb9\xe2\xe2\x74\xf7\x0f\x9f\x0b\xbf\xa3\x5f\x78\x33\xfa\xa2\x11\x8c\x76\x70\x3c\x48\xa3\x37\xee\xdd\x1d\x0f\xb7\x34\x54\x81\xd6\x9c\x3a\x6b\xd7\x4c\x03\x66\xb8\x41\x61\x74\x39\xab\x58\x29\x96\xaf\x07\x9b\x48\x3d\x1c\x08\xd0\x8d\x94\xd9\xe9\x11\xaa\x34\xce\x42\x23\xea\x08\xd1\xe3\x73\x45\xc8\xe9\xee\x1f\xbf\x1d\xbe\x1d\x36\xba\x0e\x0f\x84\x28\x18\xee\xe0\x10\x91\xc6\x12\x7f\x99\x9d\x9f\xd5\xd4\x99\x14\x79\xe6\xb6\xf5\x65\x18\x29\x3f\xe8\x39\x70\x11\x67\x05\x1d\xbd\xb0\x2c\x03\xa6\xb5\x8c\x39\x33\x98\xd0\xde\xad\x8e\x60\x69\x20\x66\x02\x6e\xd0\x2a\x2f\x34\xd2\xa9\x48\xae\x30\x67\xca\xe6\xe3\x66\x23\x45\x53\xa5\x26\xee\x2e\x34\xda\xde\x36\x90\xf0\x34\x45\x85\xc2\xce\x1c\x59\x6a\xfc\xa1\x5f\x4c\xa3\xe4\x1a\x36\x2c\xc1\xe1\xf8\xb7\xad\xa6\xbd\x5b\xc1\xde\x13\xe7\xcd\x2f\xd6\x65\xe5\x16\x63\x67\xb7\xd8\x7d\x98\x8f\x47\xee\xf8\xeb\x02\x46\xfd\xbb\xf6\x56\xc2\xed\x80\xf7\x28\x71\x1f\x48\x44\x25\xa8\xac\x12\xbf\xfb\xec\x4f\xcc\x76\xfb\x79\x27\xc6\x24\x1a\x45\xd1\xcc\xb6\x73\x07\x6a\x17\x50\xb7\x73\x07\x6b\x7d\x0d\x9d\x6c\xd9\xb2\x3e\x05\xb9\x80\xaa\x71\xff\xc1\x4b\x9f\xb2\xba\x79\xa9\x70\xb1\x28\x03\xd3\x77\xbe\xd4\x3e\x60\xea\xee\xda\xb6\x04\x22\x1f\xaf\xb9\x5f\x8a\xb5\x8f\xf4\x3a\x1b\xe2\xe1\xc1\x69\xef\x49\xde\x62\x01\xf0\xcb\xa1\x03\x40\x83\x59\x16\x4c\x21\x5e\x96\xda\x8c\x0c\xce\x18\x9d\x80\x90\x09\xcd\x36\x98\x01\x07\x63\x21\x30\x36\x84\x6d\xea\xc4\xca\x4c\x1a\x5b\xe5\x13\xb7\x57\x0e\x9f\xed\x1a\x2a\xf7\xa7\x85\x4c\xad\x0a\xc7\x75\x65\x62\x38\x4c\x15\x0a\xbb\xa9\x56\xe6\xdf\x69\x7b\xee\x87\xac\x9d\xca\xdc\xd0\x41\x9b\xd5\xe3\x36\x11\x30\x68\xd7\x9b\x23\xed\xbd\xf8\x93\xf6\xe1\x53\xa9\xe0\xb7\xb9\xb5\x9d\x0e\xae\x29\x8c\x34\x06\xab\x78\x24\x73\x33\x25\xed\xb3\xf1\x68\xb4\x1f\x77\x33\xe9\xe0\xb1\xed\x65\xb9\x7d\x7e\xe8\x40\x86\xf6\xd5\xab\xd3\x4f\x3a\x42\x5f\x29\x59\xe4\x3f\x04\x27\x27\x8d\xf3\xef\x7f\x57\xfb\xfd\xdf\xeb\x7f\x92\xa4\x3b\x38\xb1\x04\xe6\x9f\xab\x78\x91\x26\xd8\xa2\x32\x3c\x46\x0d\x37\x6e\x75\x2b\x15\x6c\xa4\x42\x7f\x1a\xbc\x88\x65\x56\x6c\x84\x8e\x68\xca\x65\x2c\x6b\xc9\xd4\xa0\x70\x4a\xe8\x6c\x82\xad\x56\x0a\x57\x74\x76\x5a\x88\xd8\xa2\x43\xcf\xa9\xba\x90\x47\xff\x90\x5c\xc0\xf4\x1b\xde\xeb\x5a\x70\x06\x93\x39\x4c\x68\x5d\x52\x9d\x70\x64\x28\xe0\xcc\xcd\x13\xb5\xbb\x2d\xf0\x12\xce\x52\x6b\x20\x17\x09\xde\xd5\xdf\x5e\xd9\xaf\x8b\x85\x2b\x66\x6c\x93\x67\x78\xe1\x1e\x69\xc2\xba\x05\xa2\x10\x77\xc4\xbf\x58\xb8\x58\xa4\xd1\x27\x7a\x45\x1a\xca\xd3\xe1\xb4\x9a\xc5\xfd\x1e\xca\x7c\x66\x2b\xd8\xef\x7f\xa7\xb6\x6e\x0e\x66\x27\x17\xbf\xff\xa1\xa5\xb8\x98\xb8\x09\x86\xdc\x70\x83\x9b\xdc\xdc\x4f\x48\xcc\x8f\x66\xe4\x8f\xc1\x7a\xae\x24\xb8\x44\x9e\xce\x22\xd2\xea\xc3\xd0\x99\x23\xbb\x51\xbc\x95\x42\x1b\x26\x8c\x05\xb2\x93\xbf\x2a\xdd\x46\x2d\xf2\x6f\xab\x7a\x32\x33\xf3\x22\xc1\xac\x7a\x3b\xb3\xc3\x09\x40\x33\x30\xd7\xca\x51\x51\xd8\xc1\xb1\xf0\xbc\xbc\x12\x10\x45\x91\x7b\xe3\x53\xab\x81\x41\x97\x5f\x0e\x4c\x65\x7a\xb5\x04\x8e\xa7\x18\x35\x88\x7c\x77\x97\xd0\x2e\x07\xf4\x61\x5f\x8e\xc7\x9d\x61\xba\x26\x2d\xda\xed\xd9\xfe\x68\x49\xf8\x58\x54\x55\x93\xd4\x8c\x7d\x72\x69\x5a\xbe\x0c\xca\x2e\xb7\xd2\xa9\x92\xcb\x3d\xf6\x64\x10\xa4\x4a\x6e\xba\x73\xf6\xbf\x33\xf0\x4f\x45\xf4\x81\x45\xdf\x21\x40\x3f\x03\x5a\x7d\x8f\x83\xc0\xda\x8c\xa9\x43\xab\x7b\x27\x55\x05\xd8\xb6\xd0\x71\xc4\x96\x2a\x4e\x03\x6d\xd5\xea\xc9\xb8\x2d\x35\x79\xe8\xb6\x8e\x89\xbd\x25\x93\xda\x6d\x13\x1f\x99\x49\xc9\x21\xe3\x41\xc7\xc4\xdd\x4b\x3c\xfd\xc7\xc3\xc1\xf1\x2f\x5d\x21\xa0\xb4\xba\xa9\x27\x00\xd5\x8d\x34\xc7\x0d\x1f\x7b\x2f\x82\xb5\x68\xa3\xba\x0d\xd6\xe6\x9b\x9e\x2b\x61\x24\xf2\xf2\xe6\x7e\xe8\x95\xb0\xb6\xca\xee\xbd\x30\x1f\xd7\xfa\xae\x57\x2a\x34\x00\xc0\x97\xaf\x15\x23\x3f\xed\x3e\x52\xb5\x0d\x54\xe9\x73\x37\x48\x6a\xae\x28\x2b\x26\x97\xa2\x2e\xae\xe5\x9d\x92\xca\xe2\xce\x2e\x40\xd3\xc3\x65\xfe\xb4\x2c\x9e\xd5\xdd\x4e\xad\x65\x51\x14\x5d\xd5\x05\xfa\x10\xcd\xf7\xa9\x8f\x6c\xf3\xc6\xc5\x93\x3e\x89\x39\xa4\xa2\x7b\x5b\xa9\x2d\xe9\x3d\x62\x29\xc2\x2a\xcc\xb8\xdf\x18\x6b\x1a\x4b\xab\x2c\x6d\x65\xe8\x42\x24\xea\x22\xa3\x3a\x2d\x03\xdf\x6d\x59\x56\xe0\x23\xbc\x52\xb2\x53\x7b\x0d\x3b\x87\xad\x0b\x75\xca\x62\xdc\xed\x67\x7e\x8d\xbc\x7b\xd0\x9c\x76\x12\xd7\xd4\xb7\x9d\x05\xa6\xd6\x0b\x72\xfb\x74\xc2\x7a\xfc\x04\x9b\x7a\x17\xe6\x1d\xa3\x76\xed\xcd\xbd\x8e\x45\xa1\x09\x9d\xed\xbb\xe6\x12\xdd\x25\x7c\x70\x15\xc8\x78\xa6\xd9\x70\xc3\xb7\xc1\xe2\x27\x0d\x4b\xad\xb1\x65\xd6\xed\x99\xfa\x65\x8f\x13\xd9\xef\xab\x95\x7d\xcf\x56\xb7\xad\x2f\xae\xd4\x96\x50\x89\xca\xf9\xaa\xb0\xab\xef\x2c\x93\xb7\x76\xc6\xba\x2e\x4b\xb0\x5d\xf5\x57\xa8\x22\xf6\xb4\xb5\x9b\x92\xbe\xb1\x42\x19\xe8\xe2\x72\x8c\x0f\xee\xb4\x9a\xd6\x16\x6b\x70\xd5\xa3\x27\x67\x88\x7f\x66\xf0\x0f\x78\xed\xd6\x19\xad\xbd\x51\xa9\x74\xf4\x01\x6f\xa7\x93\x7a\x5a\x78\xd1\x47\x6d\x51\xe5\x3e\xae\xe9\x2c\x8b\xc5\x6b\x8e\x5b\x76\x93\xa1\x73\x07\xc9\x5b\x77\xd0\xac\xc5\xac\x99\x80\xd7\xce\x11\x93\x72\x45\x53\xce\x30\x4a\x23\xdc\xd0\x87\xc1\xe4\xbc\x07\x27\xdd\x7d\xde\x51\x70\xa7\x68\xeb\xcf\x50\xf7\xe3\x46\xf8\xeb\x2c\x29\xdf\x1c\xcd\x94\xc7\xc7\xf1\xc1\x3d\x60\x53\x2e\x2a\xb7\xf3\x07\x9d\x10\x82\x62\x56\xfb\x2c\x74\x44\x98\x31\x0d\x1f\xb4\xee\x54\x3d\x54\xe2\xdb\x65\xf3\x58\x61\x27\xf9\xc7\x16\x76\x37\xef\xe8\xa9\xeb\xee\x43\x7f\x61\x6f\x4f\xaf\xaa\xca\xde\x99\x9c\xf5\x94\x76\xdf\xa3\xaf\xc7\x3e\xed\x07\x94\xf8\x8e\xee\x01\x35\xbe\xaf\x9e\x93\xd6\x13\x2a\x7a\x6f\x01\xab\x66\x9c\x8f\x2f\x60\x2d\x07\x97\x10\x6e\x9b\xf9\xc4\x12\xd6\xe9\xe5\xbf\x5d\xc3\x4e\x32\xeb\x91\x55\xac\x6b\xd4\xdf\xbe\x8c\x55\x2b\x85\x83\x65\xcc\x49\x58\xe2\xee\xaf\x5c\x83\x1d\xfb\xe4\xda\xd5\x75\xef\xa3\x8b\x57\x7b\x74\x47\xab\x57\xed\x85\x27\x94\xaf\x87\xf0\xf1\x37\xa9\x5f\x27\x47\xf3\x31\x15\xac\x3f\xf9\xff\x82\x12\xd6\x29\x10\xc7\x6a\x98\xf6\xdb\x2f\x8f\x28\x62\xe5\xdf\xff\x04\x00\x00\xff\xff\x12\xcb\x27\x8b\xe3\x35\x00\x00") +var _templateBuilderMutationTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5b\x5b\x73\xdb\xc6\x15\x7e\x26\x7e\xc5\x09\xc7\xf1\x10\x2a\x03\x3a\x79\xab\x52\x3d\xb8\x96\xd3\x6a\xa6\xb5\x3b\xb1\xd2\x17\x8d\x26\x59\x63\x0f\xa5\x1d\x83\x00\xba\x0b\x52\xd2\xb0\xfc\xef\x9d\x3d\xbb\x0b\xec\xe2\xc6\x8b\xe5\x38\xcd\x43\x46\x04\xf6\x72\x2e\xdf\xb9\xc3\xdb\xed\xe2\x2c\x7a\x53\x94\x4f\x52\xdc\xdd\x57\xf0\xc3\xab\xef\xff\xfc\x5d\x29\x51\x61\x5e\xc1\x4f\x2c\xc5\x8f\x45\xf1\x09\xae\xf2\x34\x81\xd7\x59\x06\xb4\x48\x81\x7e\x2f\x37\xc8\x93\xe8\xfa\x5e\x28\x50\xc5\x5a\xa6\x08\x69\xc1\x11\x84\x82\x4c\xa4\x98\x2b\xe4\xb0\xce\x39\x4a\xa8\xee\x11\x5e\x97\x2c\xbd\x47\xf8\x21\x79\xe5\xde\xc2\xb2\x58\xe7\x3c\x12\x39\xbd\xff\xc7\xd5\x9b\xb7\xef\x3e\xbc\x85\xa5\xc8\x10\xec\x33\x59\x14\x15\x70\x21\x31\xad\x0a\xf9\x04\xc5\x12\x2a\xef\xb2\x4a\x22\x26\xd1\xd9\x62\xb7\x8b\xa2\xed\x16\x38\x2e\x45\x8e\x30\x5d\xad\x2b\x56\x89\x22\x9f\x82\x7d\xf1\xa2\xfc\x74\x07\xe7\x17\xf0\x91\x29\x84\x17\xc9\x9b\x22\x5f\x8a\xbb\xe4\x5f\x2c\xfd\xc4\xee\x50\x2f\xda\x6e\xa1\xc2\x55\x99\xb1\x0a\x61\x7a\x8f\x8c\xa3\x9c\xc2\x0b\xda\x2e\x56\x65\x21\x2b\x98\x45\x93\xed\xf6\x3b\x90\x2c\xbf\x43\x78\x91\xeb\xd3\x5e\x24\xef\x0a\x8e\x4a\xaf\x9a\x4c\xa6\xfa\x9a\xee\xc9\x0b\xfd\x38\xf7\x1e\x4c\xcd\x39\x98\x73\xbd\x2f\x8e\xa2\xb4\xc8\x15\x1d\xbf\x58\xc0\xfb\x12\x25\x51\x0e\xd5\x53\x89\x2a\x89\x26\xef\xcb\x37\x12\x35\x55\x00\x70\x01\x98\x57\x89\x7b\xa2\xdf\x5d\x62\x86\xe1\x3b\xf3\xa4\x79\xf7\x3e\xc7\xd6\xbb\xf7\x39\xbd\xfe\xa5\xe4\xad\x63\xcd\x93\xe6\x9d\xbf\xb5\x7e\x12\x11\x9d\x9a\xef\x9a\xc4\x51\xb1\x5c\x3f\x95\x68\x44\xf0\x8e\xad\x34\xff\x70\x01\xd3\xe0\x41\x47\x20\xdb\xed\xd0\x71\xa4\x4a\xa7\x5c\x7a\x97\x27\xff\xb4\x3f\xed\x69\xd1\x62\x01\xc1\xaa\xdd\x0e\x24\x5a\x2c\x2b\x60\x39\x14\x8d\x8c\xef\x59\x05\xb4\x10\x09\x6b\xdb\x2d\x94\xd9\x5a\xb2\xcc\xa3\x4e\x9f\x97\xd3\xfd\x16\x90\x77\x92\x95\xf7\x49\xa4\x99\xef\x5c\xa4\x2a\xb9\x4e\x2b\xd8\x46\x93\x94\x70\x10\x4d\x8a\x12\xde\x97\xd1\xa4\x7a\x2a\xf5\x4b\x91\xdf\x69\x66\xf5\xf1\x57\x97\xc9\x5f\xd7\x22\xe3\x28\x7f\x12\x98\x69\xd6\xe1\xac\x7e\xa3\x85\x46\xe2\xf3\x44\xbb\xb4\xfc\xd2\x72\x2b\x5c\xbd\x61\xd9\x7f\xce\xb2\x39\x84\x4e\x11\x4b\xf7\x2c\x79\xb7\x5e\xa1\x14\xa9\x79\x37\x61\x9c\x1f\x71\x8c\xd5\x52\xf0\x77\x9a\x21\x93\xc8\x2d\x61\x2b\x56\xde\x18\x56\x6f\x3f\x16\x45\x16\xf0\x80\x96\x87\xb7\xfc\x0e\x55\x48\x1b\x26\xbf\xe4\xe2\x3f\x6b\xba\x0a\xbc\xff\x34\x11\xd8\x4f\x1b\x1a\x76\x7c\x79\x4d\x1c\x31\xfd\xdb\x0c\x41\x86\xf8\x4c\x1d\x78\x97\x66\xa8\xf7\xba\x5b\xa3\xee\x2d\xdd\x2b\x71\x55\x6c\x86\xee\x3d\xe8\x88\x01\xf1\xee\xa2\x68\xc3\x24\xfc\x4a\x86\xe8\xc0\x0e\x17\x30\x3b\x6b\xa1\x2f\x9e\xe5\x22\x8b\x23\x02\x2c\x3e\xb4\xa1\x99\x92\xcf\x50\xfa\x15\xd4\xcf\x97\x85\x74\x50\x4f\xa2\xe5\x3a\x4f\x7b\x76\xce\x52\x30\x60\x9e\x03\x81\x39\x86\xf6\xc5\x1a\xef\x12\xab\xb5\xcc\xe1\x65\xeb\xd5\x36\x9a\x58\x53\x38\x77\x42\x4e\xe7\xd1\x64\x52\x94\xe7\xbe\xe0\x8b\x52\x3f\xac\x9e\x82\xa7\x1d\xcf\xa1\xd7\x04\x58\x3b\x87\x15\xfb\x84\xb3\x16\xe2\xe2\x79\x34\x21\xb1\x2d\x16\xf0\x26\x13\x3a\x84\x19\xea\x14\x30\x62\xff\x37\x2d\x49\xf3\xe6\x37\x58\xca\x62\x45\x76\xed\xa8\x4e\xe0\x6a\x19\x3c\x80\x07\xa6\xf4\x59\xf8\x88\xe9\xba\x42\xae\x1d\x01\x83\x4a\xb2\x5c\xb1\x94\x16\xcc\xf4\x81\xd7\x8f\xf1\x3c\x7c\xce\x32\x48\xcd\xfd\x42\x59\x12\x74\xb0\x24\x39\xcf\x56\x6d\xe7\x11\x5b\x62\x67\x31\x9c\x59\xb2\xb5\x1f\x31\x7f\x9d\x5f\xc0\x4b\xf3\x70\xeb\xc4\xb9\x4a\xcc\x5f\x3b\xb7\x28\x11\xb9\xa8\x66\x71\xad\x0b\xf3\xd4\x0a\xe2\xfa\xb1\x11\x42\x6e\x24\x70\xfd\xf8\x1b\x01\xc0\xd1\xa0\x8c\x3f\x7c\x40\x89\x01\xaf\x1e\x47\xea\x47\x7d\x96\xa8\xfc\xb3\x50\xca\x42\x42\x51\xdd\xa3\x7c\x10\x0a\x47\xf8\xbb\x7e\x9c\xc5\x30\x3b\xbb\x7e\x9c\x9b\x4d\xb1\x66\x50\x2c\x61\xf2\xeb\x1c\x8a\x4f\x9a\xc7\x55\xc2\xa5\xd8\xa0\x4c\x66\x67\xd5\xe3\x25\xfd\x19\xff\x08\xdf\x14\x9f\xf4\x4a\xc7\x57\x2e\xb2\x39\x2c\x57\x55\xf2\x56\x1f\xb2\x9c\x4d\x5d\x7c\xdf\xed\xce\x1b\xa5\x09\x05\x79\x51\x81\x5c\xe7\xb9\xc8\xef\x3a\x3a\x9b\xc6\x1a\x24\x93\xea\x91\x44\x7b\xfd\xd8\x27\xd6\xea\xb1\x2d\xd2\xea\x71\xae\xaf\x8f\x28\x12\x19\xbf\x45\xfe\xfa\x17\x85\xf2\x92\x72\x0f\x63\xbe\x8b\x05\x7c\xc0\xea\xea\x12\x14\x56\x8a\xc0\xb4\x61\xd9\x1a\x4d\xf6\x82\x20\x38\x2c\x35\x80\x13\x78\x57\x50\xe8\x61\xd5\x9c\xd2\x1a\xda\xd9\xc4\x27\xa1\x80\xa5\x29\x96\x5a\x11\x45\x9e\x3d\x41\x91\x43\x18\x4b\xc9\xaa\x35\x68\xa3\x89\x13\x7b\xc7\x2d\x18\x52\x66\x82\x43\x3b\xbe\x90\x02\x26\xab\x64\x30\x22\x5d\xc0\x4b\xc1\xb5\xa0\x3c\x7f\xa4\x11\x70\x75\x59\x23\xc0\xf2\x63\xf8\xb3\x21\xb2\x31\xa5\x80\x3f\xbd\x90\xf0\xa3\x80\x6d\x98\xc8\xd8\xc7\x0c\x0d\x5f\x62\xa9\x41\xf5\xc0\x14\x94\xb2\xd8\x08\x8e\x1c\xaa\x82\x76\x7c\x34\x14\x35\xa8\xea\xb2\x77\x75\xa9\x61\xd5\xc3\xde\x1c\xf0\x51\xa8\x4a\x91\xdb\x77\x60\x1b\xe3\xf6\x42\x2b\xd7\x83\x1a\x41\xc4\xaa\xfe\x6c\x78\xe3\x1c\x2a\xb9\x46\x03\x8a\x91\x68\x4d\x30\xd5\x8f\x25\xa6\xa8\xa1\x5d\x07\xe4\x0f\xe4\xbc\xea\x45\xc4\xea\xf9\x05\x94\x52\xe4\x15\x4c\x3f\x60\x35\xd5\x4b\x3f\x50\xa8\x70\x97\x9a\xa5\x26\x77\xac\xd7\x7a\x89\xe6\x34\xa1\x4d\x6f\xf4\x02\x96\x57\x0e\x96\xf5\xf9\x3a\x5b\x71\xe0\x34\x81\xde\x61\xca\x40\x73\x0c\x50\xde\x21\x33\xc3\x95\x0e\x02\x7e\xb6\xe0\x23\xab\x9b\x59\x5c\x98\x38\x51\x36\x19\xc0\xe2\x4c\x53\x53\x69\x29\xe4\x36\x3b\xa1\x04\xab\xd8\xa0\x94\x82\x23\x94\x12\x37\xa2\x58\x2b\x48\x59\x96\x29\x8d\x8e\xd7\x9c\x27\x40\x99\xff\x9e\x04\x67\x95\x0c\xa6\x38\xa4\xf0\x56\xe8\xdd\x45\x8d\xa0\xea\x78\xfb\x37\xac\x4c\x22\xd9\x80\x3e\x14\x5a\x3f\xfe\xf7\x0a\xb1\x75\x81\x06\xb2\x0c\x25\xd9\x05\xf1\x64\x63\x5c\x65\x2f\x4b\xd1\x44\x83\x7c\xe3\x63\xb9\x06\xb3\x46\x73\x0d\xe7\x8d\x45\x2d\xf1\xbb\xdd\x6a\xf1\xb1\x9c\xf7\x8b\xb0\x07\x94\xaf\x39\xef\x05\x65\x1b\x63\x8c\x73\x05\x35\x46\xaa\x22\x14\x5b\x12\x4d\x9e\x01\x66\xc6\xac\x07\x95\xfc\x8d\x27\x8a\xc9\xd9\xc8\xc2\x3f\x5d\x80\x07\xcb\xc9\xce\xe4\x88\x66\xdf\x28\x88\x5e\x06\xdb\x48\xd0\x46\x12\xaf\x39\x47\xbb\x2b\x14\x54\x80\x24\x83\x1d\x13\x7c\x99\xd2\x22\x6b\xfc\x5f\x8f\x69\x1a\x94\x09\xe5\xc3\x6c\x44\x8a\x83\x34\x1c\x06\x36\x87\xb6\x21\xf6\xad\xfc\x43\xc4\x35\x90\x9b\xec\x1a\x04\x7a\xa0\x9b\x18\xff\xe5\x42\x8a\x05\xe0\x8b\x65\xf2\xbe\xb4\x99\xd3\x10\xf0\xde\xe8\x04\xf0\x20\xe8\x51\xaa\xd8\x8a\xbe\x27\xa2\xcf\x8a\x62\xd8\x9f\x19\x37\x32\xee\x87\x0e\x71\x44\x81\x27\xd2\x3b\x82\x7c\xf7\xa6\x71\xf9\xbb\xdd\x2d\x5c\x34\xc2\xf4\x65\x55\x07\x83\x50\x44\x46\x72\xc8\xa7\xbd\xc2\x72\x78\x14\x26\x43\x31\x40\x0b\xc1\xa7\xb1\x69\xc9\x39\x12\x82\xa1\x28\x35\xb6\x7c\xc7\x04\xa3\x5c\xf6\x62\x25\x64\x74\xfa\x33\xaa\x81\x18\xd9\xe1\x52\x61\x05\x2c\xcb\x20\xbd\xd7\x71\x5a\xb9\x8c\xec\x73\x22\xe0\xbe\x58\xd7\x84\x98\xe7\x0a\x51\xde\x61\xa1\xbd\x4c\x38\x75\x78\x66\x2d\x89\xce\xc1\x17\x69\xdc\x09\x78\x9e\x74\xbd\x14\xa6\x5b\xac\xeb\x53\x0a\x4a\x61\xa6\x8c\x13\x90\xac\xdd\x7a\xc5\xbb\x5d\x73\x01\x53\xd2\x09\x3d\x68\xaa\x5a\x78\x21\xb8\xfa\x29\xb0\xe8\x59\xc9\x54\xca\x32\xbd\x2b\x86\x99\x12\xf9\xdd\x3a\x63\x52\x9f\x49\xea\xf8\x2f\x98\xf7\x31\x4c\xaf\x2e\xd5\xf0\x9d\xee\xdc\xfe\x63\xdd\x0f\x73\x28\x9d\xd5\xa2\xcd\x22\xc5\x1d\x63\x23\x4d\xa1\xbd\x7a\x13\xef\xb1\x86\x08\xf2\x3b\x74\xe1\xcc\x56\xf5\xee\xd5\xc7\x27\x10\xdc\x10\xa9\x2b\x10\x9f\x50\x55\x5f\xb8\x17\x5d\x0d\x21\xb3\x2e\xc3\x74\xbe\xed\x60\x08\xae\x20\x49\x92\xfa\x64\xe8\x6d\x34\x18\x90\xf6\x35\x5b\x6a\xbf\xd6\x6d\x5b\xd8\xf4\x3f\xe8\x97\xb8\x70\x3b\xb0\xc3\x0f\x02\xc3\xc7\xd6\x65\xfb\x78\x53\x24\xae\x03\x88\xae\x53\x05\xe5\xce\x84\x4d\xcd\xf3\xe8\x1d\x37\x82\xab\x1b\x71\xab\x7d\xa4\x3b\x6c\x5b\x47\xe7\x10\xfc\x93\xae\x78\xc7\x23\x0f\x1e\x13\x79\x0e\x45\xcd\x09\xb1\x68\xb4\xd3\xb5\x2f\x36\xe0\xe9\xb1\x81\x98\x08\xf9\xf2\x42\xc3\xf3\x44\x82\x5e\xa6\xbc\xc4\xca\xbc\x0f\xf5\xd0\x2a\x4a\x43\x0a\x05\xef\x49\xce\xf7\x10\xda\xbd\xc0\x2b\x34\x3b\xa8\xed\xcb\x9d\x46\x2c\xe5\x9b\x6e\xba\xe4\x6a\xcc\xce\xe2\x3a\x6b\xf2\xb3\xa9\x26\x30\xd6\x96\x59\x57\x98\x59\xf1\x80\x12\x66\xa4\xeb\x25\x4c\xbf\x4d\xbe\x57\xd3\x00\x71\x71\xb3\xa1\xe3\x90\xa7\x3f\x53\x2b\x73\x7a\x90\x33\x6e\xd4\xe1\x79\x4e\xd3\x0b\x3d\xc5\x6d\xaa\xfd\x5a\xf1\x1c\x63\xe3\xfa\x86\x1c\x9e\xd1\xc0\x68\x6f\xb6\xe5\xb2\xc6\xd7\x1e\xef\xb9\x06\x5c\xee\x9e\x9b\x6e\x04\xef\xfa\xae\x96\x1b\x1e\x76\x8a\xfb\x0f\xef\x77\x8e\x0d\xc5\x75\xa6\x11\xba\x8f\x36\x46\xf8\x41\xee\xd0\xb7\x4a\x4b\x17\x11\x6b\xf3\xf1\xe3\x7d\xe0\xd5\xa5\x32\x96\xa8\xe0\xe6\x76\x4c\xfb\x24\x21\xde\x88\x68\x8f\x7a\x8d\xf4\xf4\xb1\x17\xc0\xca\x12\x73\xae\xef\x98\x83\xe0\xf1\xa0\xf1\xb9\xac\x74\xd0\x29\xa9\x51\xaf\xa4\xba\x6e\xc9\x4c\x22\xfa\x50\x43\x83\x37\xdb\x50\xa3\xbd\x2c\x7b\x60\x4f\xcd\x05\x19\xe6\x9a\xe0\x18\xfe\x72\x01\xdf\x53\x6f\x77\x6d\x76\x6b\xb3\x53\x73\x2a\xf0\x9f\x8a\x35\xa8\xfb\x62\x9d\x71\x58\x2b\x1c\xf5\xa6\x22\x57\x15\x32\x9e\xc0\x55\xe5\x7c\x1b\x75\xeb\x48\xaa\x79\x85\x52\xe7\x9d\x6b\xc5\xee\x50\x1b\xaf\xd7\xad\x73\x43\x41\x87\xa2\x63\xdd\xec\x21\xda\xd5\x52\x1a\x32\x2e\xb1\xb4\x5a\x1f\xf0\xa7\x3f\xea\xd7\x81\x03\xee\xea\xfc\xcc\x53\x7a\xcb\xf0\xba\xa8\x3a\x19\x4e\x56\x4a\xbb\x5d\xd0\x73\x8c\x7a\xfb\x80\xae\xca\xe9\x1a\xdc\x31\x55\x4e\xe8\x8b\x4f\x2a\x72\xfa\xfc\x62\x58\xe4\x74\xf2\xcb\x3d\xb9\xca\x92\x65\x84\xc5\x96\xa0\xf7\x7a\xe3\xbe\xee\x9d\x5f\xcc\xd0\x44\x3d\xb0\xbf\xa6\xb9\x9e\x37\x43\xaf\x5e\xee\xdf\x97\x33\xfd\x3f\x6f\xb8\xb5\x4a\x8a\xd2\x8d\x53\x34\x10\xfd\x73\x73\x37\x10\xaf\xbf\x50\xa8\x0f\xa3\xde\x55\xdd\xb2\x8f\xc7\xee\xd4\xc7\xce\x62\x3b\x29\x0e\x6e\xae\x9e\xdc\xd5\xb6\xa3\x5c\x4f\x60\xb2\xcc\xd4\xab\xfe\xf8\xc6\xe8\x9d\x03\x5f\xd3\xc8\x79\xb1\x68\x55\xeb\x7e\x5f\x5e\xe4\x50\x48\xfa\x42\xa3\x80\x3b\x8b\x1b\xdb\x83\xd5\x1b\x3b\x67\x8b\x7c\xc1\x31\x95\xb8\xc2\xbc\x42\x3e\xa7\x86\xac\x69\x32\x19\xca\x66\xa3\x1c\xba\x35\x70\x73\xdb\x70\x69\xef\x38\xb7\xe1\xd5\xbd\x9a\xc3\x2b\xaa\x5c\x33\xcc\x83\x56\x7a\x7c\xc0\x5c\xfc\xbb\x63\x7b\xe3\x4d\xae\x36\xde\x41\xb4\xb4\xd6\x16\xbd\x1c\xa8\xb0\x5b\x33\x72\xab\x48\xb3\xda\xd7\x64\x4f\x27\xb0\x58\x02\xb3\x1d\x98\x07\x51\xdd\x9b\xaf\x0e\xc4\x06\x1d\x66\x35\xfe\xee\x11\x14\xa6\x45\xce\x29\xdd\x44\x96\xd7\x1d\x68\x2e\x52\x1a\xf4\x92\xc6\x48\xed\xf6\x28\x33\xc5\xd4\x25\xa9\xc2\x6a\x0e\x85\xa4\xb4\x5d\xff\xb6\x9f\xcd\xd8\x48\xa4\xd2\x7b\x5c\xb1\xbd\x4a\x9c\x69\x62\x2c\x54\x63\x33\x02\xfd\xb7\x26\x61\xde\x24\xc0\xea\x41\x54\xe9\x3d\x51\xad\x7f\x7e\x01\xa5\xa5\x4c\x61\x20\xfa\x73\xaf\x9a\xa8\xf5\xd9\x6e\xb2\x47\xed\x12\x30\x98\x2c\x92\x2f\x32\x1a\xfa\x80\xd6\xcb\xb6\xe6\x78\x3a\x02\xb4\xb4\xa2\x83\x64\x33\x15\xa5\x79\x31\x0d\x46\x83\x86\x9a\xf0\xe5\xcd\x43\x81\x93\x46\xcc\x6a\x32\x58\xed\x4b\x56\x42\xad\x98\x16\x61\x73\x84\x7e\x3e\xa6\x1b\x47\xb2\xaf\x9e\xb9\x25\xbb\xd6\x51\x6c\x89\xfb\x8a\x3a\xda\xb8\x99\x2f\x91\x96\xcc\xc2\xbe\xbe\x8d\xe2\x6e\xf2\x5b\xab\xd4\x1f\xfb\xae\x73\x7c\x2c\x31\xad\xd0\x08\x05\xbe\xbd\x26\xbd\x18\x31\x7d\xab\xa6\x96\xeb\x39\xf1\xd6\x24\x70\xab\xe4\x03\x56\xbd\xfd\xf0\x4d\xec\x81\x87\x42\x4b\x3f\x4c\x42\x22\x3e\xe5\xc5\x43\x7b\x2c\xeb\xd1\x60\x2e\x37\x70\xf2\xbc\x64\xe0\xbf\xdd\xc8\xab\xc7\xd7\xd6\x8e\x56\xef\x2f\x24\x78\xae\xd7\x7a\xf7\x76\x23\x76\xcf\x24\xa0\xd7\x01\x37\xc3\xec\xbf\x33\x15\xb4\x26\x37\x4c\x3a\xb2\xdc\x06\x0b\x83\x11\x94\xec\xe9\x83\x9f\x02\xa2\xa3\x86\x3c\x07\x3b\xe9\xbe\x8a\x27\xf8\x11\xba\xed\x56\x7e\x32\x80\x94\xb6\xae\xc3\x3c\xc1\x8a\xa2\x35\xf3\x09\x83\x2a\xc5\x5d\x59\xac\x46\xc3\x80\x1f\x03\x5a\xbe\xdf\x04\xfc\x8e\xfb\x7f\x16\xdf\xdf\xf0\x75\x40\x00\x18\xc6\x55\xcb\xed\x7c\x15\x44\xf5\x3b\x26\xaf\x19\x35\x32\x3a\x1b\x87\x4d\x7f\xf0\xef\x84\x97\xd7\xdc\x22\x84\xa6\xa4\xff\x17\xe1\xc5\x91\xfc\xe5\xc2\xcb\xa0\x96\x4f\x52\xf2\x80\x8e\xf7\x47\x9f\x30\xfc\x3c\x4f\xfc\x99\xb8\xd6\xcf\x6b\xde\x0f\x2b\x13\x81\x02\xc7\x32\xf8\xd5\xe5\x31\xf1\x28\x08\x30\xad\xb8\x64\x3e\x93\xf3\xbf\xe0\x0c\x43\x53\x66\xbe\xd3\xe9\xd6\x18\x66\x8f\xde\x7e\x6c\x20\x0a\xae\x1b\x0b\x45\xe1\x74\xeb\x73\x63\x51\x6b\x56\xf6\x39\x71\x68\x6c\x2c\xfb\xc7\x89\x41\x44\x9e\x15\xb6\xf7\x0d\xa4\xab\x18\x9a\x5a\x41\x2c\x7b\x2a\x85\xe1\x59\xef\x9e\xca\xc0\xde\x18\xc6\x07\xd7\xeb\x1f\x98\xf9\xea\xb5\xb7\xf5\x47\x9b\xc8\x6c\x64\xef\xcc\xf0\xbf\x84\x6b\xdc\x0b\xd5\x9e\x70\x57\x3b\xb8\x11\xbc\x9e\x1e\xe3\x9e\x07\xa9\x43\xf1\x6d\x95\x10\x57\xc3\x81\xad\xe5\x81\x8e\x0e\x74\x87\x38\x24\xdf\xad\xf4\x78\x24\x6a\x76\xb9\xf4\x89\xaa\x2f\xbf\x9f\xd5\xea\x99\x82\xc4\x3b\x26\xb9\xf1\x41\x14\xde\x0c\x3c\xcc\xe1\x3d\x20\x19\x46\x08\xb9\xb3\x63\x41\xd2\x10\x3b\x00\x92\xaf\x55\x64\xad\x12\x22\x6d\x58\xd3\x5f\xba\xd8\x31\xdf\x0e\xf8\x01\x85\x26\x40\x7a\x9d\x1f\x4b\x14\x56\x0b\xf3\xd9\x93\x75\x36\xfa\x80\x83\x4b\x1a\xba\xa4\x15\x46\xa8\xe3\xbd\xaf\xa3\xe4\xbe\x6c\x88\xf7\xfd\x23\x85\x03\xe7\x78\x87\x28\x0e\xdb\x66\x6a\x28\xad\xc3\x84\x6d\xd5\x1f\xd6\x4e\xa2\xc5\xbe\xbc\xfd\x71\x83\x96\xb6\xe0\x0a\x66\x55\x61\x3e\xcf\x36\xff\x8e\x25\xf6\xe4\x6e\x64\xbe\x2c\xa4\xa9\x18\x9c\x5b\xad\x75\xb4\x57\xf4\x57\x97\x2a\x84\xfc\xcd\x6d\x9d\x05\x8e\x03\x7f\xe0\x9f\x82\x1c\x2b\xbe\x7e\xdc\x0f\x0d\xdd\x8e\x1f\x0c\x38\x49\x7b\x7c\x6d\xcf\x04\x6f\x8f\xcb\xbc\xa9\x9c\x08\x3a\x99\x5e\x55\xf4\x6a\x4e\x03\x9a\x81\xab\xe3\xb8\x99\xe9\x1d\x3c\x5b\x18\x1e\x2e\xd8\x54\xd3\x52\x2f\x74\xe2\x70\x48\x2a\x69\x3f\x6e\x27\x07\x4c\x9d\xf7\x03\x0d\xb8\x1e\xeb\x1d\x67\xbe\xfe\x25\x5f\xd4\x80\x2d\x20\xda\xdf\xe3\x1c\x36\x21\x0e\x00\x71\x92\x8d\x1f\x68\xe4\x9d\xaf\x53\xf6\x98\xbc\x15\xdf\x91\x46\xef\x74\x75\x9a\xd9\x37\x77\x3e\xaf\xe1\x0f\x68\xe7\x24\x71\x0f\x24\x3e\xfb\x2d\x73\x0c\x06\x83\x06\x7a\xc0\x48\xf9\x38\x3b\x3d\xc6\x4c\x6d\xae\x7d\xa0\x99\xb6\x52\xfa\x43\xcd\xd4\xbf\xe4\xf7\x30\xd3\x5e\x13\x1d\x1d\x21\xfe\xf1\x6c\x53\x73\x75\x4c\xe9\x45\xfa\xfa\x8c\xca\xcb\xbb\xaf\xbf\xf0\x3a\xc5\x22\xbf\xa4\x35\x1e\xfa\xc9\xd7\x01\xfd\x0f\xaf\xa5\x46\x22\xd0\x8c\x3c\x47\xe9\x58\xdb\xd0\xe7\x95\x8f\x9a\x9c\xbd\xd5\xa3\x27\xfc\x91\xba\xb1\x47\x55\x83\xc9\xce\x69\xd6\x70\x40\xd1\xd8\xfe\x00\xe1\xf7\x2a\x1a\xbd\x8f\x59\xba\xe5\x06\x15\x3a\xa4\xf8\xd3\xeb\xc5\x26\x00\x8e\x95\x8b\xb4\xea\x73\xab\xc5\x11\x4c\x7c\xa5\x9c\xd9\xab\x15\xfb\x15\xfc\x1c\xb5\x62\x57\x77\xde\xe7\x1a\xf5\x9f\xff\x0b\x00\x00\xff\xff\x78\x78\xbf\x1a\x8e\x42\x00\x00") + +func templateBuilderMutationTmplBytes() ([]byte, error) { + return bindataRead( + _templateBuilderMutationTmpl, + "template/builder/mutation.tmpl", + ) +} + +func templateBuilderMutationTmpl() (*asset, error) { + bytes, err := templateBuilderMutationTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "template/builder/mutation.tmpl", size: 17038, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templateBuilderQueryTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x6d\x6f\xdb\x46\xf2\x7f\x4d\x7d\x8a\xa9\xe0\x1a\x52\xa0\x50\x49\xde\xfd\xfd\x87\x0f\x70\xe3\xe4\x20\xa0\x48\xaf\x49\x80\x16\x08\x82\x96\x26\x87\xd2\x36\xd4\x2e\xbb\xbb\x94\x6d\xe8\xf4\xdd\x0f\x33\xbb\x7c\x10\x49\x59\x94\xed\xeb\xf5\x95\x44\x72\x76\x76\x67\xe6\x37\xbf\xd9\xa7\xed\x76\xfe\x62\xf4\x56\xe5\xf7\x5a\x2c\x57\x16\xde\xbc\x7a\xfd\x7f\x2f\x73\x8d\x06\xa5\x85\xf7\x51\x8c\x37\x4a\x7d\x83\x85\x8c\x43\xb8\xca\x32\x60\x21\x03\xf4\x5d\x6f\x30\x09\x47\x9f\x57\xc2\x80\x51\x85\x8e\x11\x62\x95\x20\x08\x03\x99\x88\x51\x1a\x4c\xa0\x90\x09\x6a\xb0\x2b\x84\xab\x3c\x8a\x57\x08\x6f\xc2\x57\xe5\x57\x48\x55\x21\x93\x91\x90\xfc\xfd\xc7\xc5\xdb\x77\x1f\x3e\xbd\x83\x54\x64\x08\xfe\x9d\x56\xca\x42\x22\x34\xc6\x56\xe9\x7b\x50\x29\xd8\x46\x67\x56\x23\x86\xa3\x17\xf3\xdd\x6e\x34\xda\x6e\x21\xc1\x54\x48\x84\xf1\x9f\x05\xea\xfb\x31\xec\x76\xf4\xf2\x2c\xff\xb6\x84\x8b\x4b\xb8\x89\x0c\xc2\x59\xf8\x56\xc9\x54\x2c\xc3\x7f\x45\xf1\xb7\x68\x89\xe0\x5b\x5a\x5c\xe7\x59\x64\x11\xc6\x2b\x8c\x12\xd4\x63\x38\xeb\x7e\x12\xeb\x5c\x69\x5b\x7e\x72\x4f\x30\x19\x05\xdb\xed\x4b\xd0\x91\x5c\x22\x9c\xe5\x91\x5d\x51\x67\x67\xe1\x27\x71\x93\x09\xb9\x5c\xb0\x94\xa1\x16\x41\x30\xe6\xe1\x90\xc8\x6e\x37\x76\xed\x50\x26\xf4\x6d\x3a\xe2\xbe\xce\x6e\x0a\x91\x91\xbb\x58\xc5\xcf\x64\xc6\x87\x68\x8d\xa5\x25\x1a\x63\x14\x1b\xf7\xb9\xfa\x5f\xb5\xa1\x41\xcd\xe7\xd0\x54\xb3\xdb\x51\x28\xc8\x8f\xe5\x9b\x54\x69\x60\xf7\x08\xb9\x24\xd1\x3c\x32\x71\x94\xc1\x59\xe8\xfb\x01\x94\x56\x58\x81\x26\x1c\xd9\xfb\x1c\xdb\xda\x8c\xd5\x45\x6c\x61\x3b\x0a\x62\xf6\xe3\x28\xc8\xc4\x5a\xd8\x20\x78\x21\xa4\x1d\x05\x2a\x4d\x0d\xd6\x4f\x3a\x41\x1d\x04\x5f\xbe\xfe\x44\x7f\x46\x41\x21\xc5\x9f\x05\xd2\x0b\x63\xb5\x90\xcb\x51\x90\x6b\x4c\x44\x1c\x59\x34\x10\x7c\xf9\x5a\x3d\x85\xd4\x6b\x39\x22\xe7\xa7\x5b\x61\x57\x70\x16\xbe\x4b\x96\xe8\x9d\x39\x9f\x03\x46\x4b\xd4\x2f\x33\x15\x25\x64\x0d\xd2\xb7\x70\x14\x34\xe3\x81\xe4\xaa\xd0\x35\x08\x48\x47\xc3\x64\xac\x6c\x7e\x41\xfd\x61\xf8\xf9\x3e\xc7\x7d\xa7\x07\xcd\x18\x75\xfe\xcf\x5f\xc0\x55\x92\x08\x2b\x94\x8c\x32\x48\x05\x66\x89\x01\xab\x20\x4a\x12\xfa\x69\xb8\x3d\x04\xc6\x28\xb7\x3a\xb3\xeb\x3c\xa3\x61\xe5\x5a\x48\x9b\xc2\x38\x11\x51\x86\xb1\x9d\x7f\x6f\xe6\x1c\x99\xb9\xd3\x34\x26\x10\x59\xa5\x3d\x4a\xb9\xad\x48\x61\x15\x99\xcf\x25\x22\x9d\xaa\x6a\x9c\x77\x76\xff\x43\xd8\x19\xf5\x7c\x0e\x42\x5a\xd4\x6b\x4c\x04\xc9\x71\x7f\x21\xc9\xec\x75\x06\xcd\xe7\xf0\x87\x1a\x5f\x0e\x61\xbf\xac\x50\x23\x59\x69\x20\x02\x89\xb7\x50\x05\x8e\xe1\xd5\xb4\x7b\x94\x16\x32\x86\xc9\x1e\x78\x4b\x87\xd7\xb0\x9a\x3a\x95\x93\xdc\x40\x18\x86\xfd\x30\x98\xb6\x1b\x11\x08\x9b\x7a\x77\xbb\xb0\x01\xa7\x4b\x88\xf2\x1c\x65\xd2\xee\xba\x21\x33\x83\xdc\x84\x61\x38\x1d\x05\x1a\x6d\xa1\x25\xb4\x44\xbd\xb5\x3f\x12\xc0\x4b\x6b\x19\xed\x60\x2c\xe6\x65\x84\xbd\x0b\x07\xda\xc9\xca\x26\x4e\x8b\x90\xf6\xa8\x51\x34\x62\x27\x7d\x09\xe7\xfc\xe7\xc8\x68\x7f\xe2\x0c\xf4\xc3\x95\xe0\x12\xf2\x09\x03\x76\xfa\x26\x5e\xcf\xd0\x21\x7b\xf1\x4b\x38\x77\xff\x8e\x0d\x9a\xf8\xa1\x1e\x33\x3f\x3d\x61\xc8\xd4\x7e\xa2\x08\x4a\xfc\x77\xd8\x88\xb9\xd3\x83\xa8\xe1\xcf\x33\x50\xc7\xf0\x42\x85\xd4\x55\x28\xae\x83\xab\xc8\x80\x11\x6b\x91\x45\x5a\xd8\x7b\x47\x62\x44\x53\x6c\x91\x40\x43\x55\x2e\xce\x04\x4a\x1b\x72\xc6\x32\x4b\x6c\xb7\x25\x7b\xfd\x36\xf3\x0c\xd6\x24\x3e\xe6\xaa\x64\x89\xbf\x35\x6a\x05\x53\x09\x4c\x6a\x66\x63\x2a\xa3\xcc\x99\xc2\xf8\xe7\xaa\x1a\x52\xfe\xf3\x53\x2f\x0b\xc6\xab\x48\x48\x57\x2d\xe2\x42\x6b\xaa\xfd\xec\x78\x50\xae\x14\x3b\x92\xac\xea\x44\xb2\xc4\x70\x14\x0c\x8c\xc9\xc1\x5e\x27\x3e\x3a\x7b\x16\xb9\x10\x05\xae\xf7\x8b\x4b\x38\xef\x91\xd8\xba\x02\x74\xd1\x8e\x42\xe8\xde\x97\x9c\xe8\x5c\x7e\x67\x89\x01\xcf\x60\xfc\xd1\x0b\x8e\x1b\x6d\xc6\xe4\xdb\x31\x79\xfa\xa5\xab\x13\xa4\xf1\x28\x49\x53\x19\x6f\x53\xf4\x43\x34\x5c\xf1\xb0\xeb\xc4\x43\x88\x75\x8d\x02\x0e\xba\x27\x69\x4a\x88\xf7\x42\x1b\x0b\x4e\xc6\x45\x24\xe5\x37\x4d\x42\x74\x95\xfa\xbe\x9c\x28\xb9\x1c\x81\x8f\xbe\xcd\x8b\x0f\xca\xbe\xa7\xc9\xd5\x3b\xad\x95\x86\xdb\x15\x4a\x90\x8a\x14\x64\xea\x96\x66\x0d\x95\x9a\xdb\xc8\xb8\x69\xd8\xe0\x04\xe3\xd1\x4d\x62\x7b\x07\xb1\x92\x16\xef\x2c\x4d\xaa\xe8\x77\x0a\x93\x17\xcd\x21\xce\x00\xa9\xf7\xa9\x4f\xb8\x3c\x2b\x34\xcf\x35\x3e\xd6\xda\x59\x84\x1c\xdd\x0e\xa3\x63\xca\xd7\xd3\xf0\x2a\xcb\xa8\xaf\xe9\x28\x10\x29\x0b\x7f\x77\x09\x52\x64\x8c\x10\xef\x45\x29\x32\xd6\x43\x8e\x24\xa9\x0c\xe5\xe4\x40\x7f\x53\xb8\xbc\x84\x57\x9d\xc6\xe7\x7b\xee\xda\x3a\x47\xd7\x73\xc4\xf0\xc7\xe8\x06\xb3\x1d\xeb\xaf\x93\xbf\x4f\xff\x97\x57\x5f\x67\xa4\x72\xd4\x08\xe4\xaf\x6e\x3e\xfc\x0d\xdd\xe3\x0c\x6e\x0a\x0b\x79\x24\x45\x6c\xa8\xa2\x47\xd2\xb9\x09\x54\x1c\x17\xda\x9c\x16\x86\x5f\xfb\xe3\xb0\x17\x86\x92\xef\x06\xf9\xbd\x0a\x6e\xc7\xe1\xe7\xe7\xf0\xdd\xc2\x94\x8e\x9a\xa0\x76\x81\x0d\xd8\x12\x7e\x6c\xf9\x67\xaf\xc3\xa6\x43\x16\xd7\xc7\xb0\x2d\x92\xd3\x70\x2d\x92\xc7\xe2\x78\x71\x7d\x00\xc9\x22\x71\x43\x5a\x5c\x33\x9b\x56\x3e\xab\x21\xbd\x89\x34\x88\xc4\xc0\x97\xaf\x2d\x41\xf6\x9c\x48\x8c\x6b\xf0\x00\xb6\x17\xd7\x86\x5d\xfd\xff\xfd\xc0\x6e\xe2\x59\x24\xa6\x81\x5d\xa7\x77\x28\x6a\x9b\xea\x7c\x78\x44\x62\x7a\xa1\xba\xb8\xde\x07\xeb\xe2\xfa\x79\xe1\x7a\xc8\xdd\x2d\x0f\x92\x91\x22\x79\x18\xa4\x4e\xd5\x13\x61\x2a\x92\x72\x0e\x22\xb3\xfb\x3d\x54\x2a\x7a\x71\x8c\x70\x67\x55\x93\xca\x2d\x22\x05\xa9\x2c\xe0\x5d\x14\xdb\x8c\x8a\x27\x96\x0d\x09\xa1\x4e\x1c\x87\x83\x94\xc6\xf5\xd7\x70\xed\x9b\xd3\xb9\xd6\xdc\x0a\x1b\xaf\x1e\xe6\x5b\x5a\x2b\xd2\xd2\xfb\xf5\x45\xad\xe4\x18\x79\xba\x16\xaf\x2e\x1e\xc9\xd2\x09\xa6\x51\x91\xd9\xbe\xe6\x9f\x84\x5c\x16\x59\xa4\x8f\xf2\x7c\x8d\x8a\x9a\xbe\xe9\xe9\xb9\xd2\x81\x35\x3f\x37\x79\x97\x60\xe9\x0d\xe0\x49\x3c\x4d\x9a\x5a\x34\xdd\x4d\x88\x16\x4b\x0f\x4b\x06\x4f\xd5\x8f\x4a\x84\xff\x1d\x59\xbf\x19\x46\xd6\x8d\x84\x60\xc2\xde\x03\xbf\x48\xe0\xd2\x13\x6f\x13\xe1\xa7\x71\x79\x03\xdb\x75\xc3\xc1\xa8\x2e\xc7\xda\x40\x77\x83\xf1\x9d\x8b\x9f\x15\xe1\xcf\xc3\xf7\x75\xec\x4f\x40\x76\x45\xed\x57\x59\x06\x78\x87\x71\x61\xd1\xd4\x68\x85\x48\x26\x35\x60\x21\x13\xc6\x82\x4a\xf7\xa8\xc9\xe3\x7c\xb0\xc5\x9e\x3e\x7b\xf0\xf9\xe5\xeb\x41\xb2\xee\x5f\x4c\x86\xad\x2d\x99\x8a\x99\x2b\x93\x6a\x5a\xba\xca\xb2\xe7\x8a\x19\xe9\xed\x37\xa1\x65\xc1\x63\xca\xcc\x43\xd5\xe5\x20\x39\xf5\xf5\xe0\x9d\xb0\xb8\x36\x27\xc5\xb5\x49\x5c\xc3\x5d\xe2\xd3\xbe\x37\xa8\x7d\x9c\x33\x88\x6f\x0e\x78\xe8\x13\xd2\x22\x73\xd2\xce\xdf\xf7\x02\xb3\x64\x71\x3d\x0d\x3f\xc5\x91\xa4\xc1\xcc\xe0\x9c\xe8\xe5\x00\x13\xed\xd7\xe8\x7a\xc2\xd7\x9c\xed\x2d\xae\x4d\x0d\xa0\xc5\xb5\x79\x2e\x00\x91\xde\x43\x00\xea\xcd\x79\x73\x10\x2e\x25\xdf\x9e\x92\xf1\xc6\x9b\xf7\x56\x15\x72\x7f\x01\x1d\xf3\x1b\x3e\x3f\x40\x58\x8a\x0d\xca\x13\xb7\x95\x58\xe5\xa1\xf2\x23\xed\xe9\x29\x5d\x29\x9c\x36\x07\x5d\x47\x85\x1f\x9f\x2b\x2e\x4e\x77\xff\xf0\x85\xf4\x3b\xfa\x85\x37\xa3\x2f\x1a\x8d\xd1\x0e\x8e\x07\x6b\xf4\xc6\xbd\xbb\x13\xcd\x2d\x0d\x5d\x20\x99\x53\x67\xed\x2a\x32\x80\x19\xae\x51\x5a\x53\xce\x2a\x96\x3a\xca\x57\x83\x4d\xe4\x1e\x0e\x04\xe8\x46\xa9\xec\xf4\x08\x55\x1a\xa7\x4d\x23\xea\x08\xf1\xe3\x73\x45\xc8\xe9\xee\x1f\x3f\x0d\x9f\x86\x8d\xae\xc3\x03\x21\x6a\x0c\x77\x70\x88\x58\x63\x89\xbf\x8c\xe6\x67\x35\x75\x26\x45\x9e\xb9\x6d\x7d\xd5\x8c\x94\x1f\xf4\x0c\x84\x8c\xb3\x82\x8f\x5e\xa2\x2c\x83\xc8\x18\x15\x8b\xc8\x62\xc2\x7b\xb7\x26\x84\x85\x85\x38\x92\x70\x83\xa4\xbc\x30\xc8\xa7\x22\xb9\xc6\x3c\xd2\x94\x8f\xeb\xb5\x92\xfb\x2a\x0d\x73\x77\x61\x90\x7a\x5b\x43\x22\xd2\x14\x35\x4a\x9a\x39\x46\xa9\xf5\xa7\x88\x31\x8f\x52\x18\x58\x47\x09\x0e\xc7\x3f\xb5\x9a\xf4\x6e\x05\x7b\x4f\x9c\xef\x7f\x21\x97\x95\x5b\x8c\x9d\xdd\x62\xf7\x61\x36\x0a\xdc\xf1\xd7\x05\x04\xfd\xbb\xf6\x24\xe1\x76\xc0\x7b\x94\xb8\x0f\x2c\xa2\x13\xd4\xa4\xc4\xef\x3e\xfb\x13\xb3\xed\x6e\xd6\x89\x31\x8b\x86\x61\x38\xa5\x76\xee\x40\xed\x02\xea\x76\xee\x60\xad\xaf\xa1\x93\x2d\x5b\xd6\xa7\x20\x17\x50\x35\xee\x3f\x78\xe9\x53\x56\x37\x2f\x15\xce\xe7\x65\x60\xfa\xce\x97\xda\x07\x4c\xdd\x5d\xdb\x96\x40\xe8\xe3\x35\xf3\x4b\xb1\xf6\x91\x5e\x67\x43\xbc\x79\x70\xda\x7b\x92\x37\x9f\x03\xfc\x72\xe8\x00\xd0\x62\x96\x35\xa6\x10\x2f\x4b\x6d\x56\x35\xce\x18\x9d\x80\x54\x09\xcf\x36\x22\x0b\x0e\xc6\x52\x62\x6c\x19\xdb\xdc\x09\xc9\x8c\xf7\xb6\xca\xc7\x6e\xaf\x1c\x3e\xd3\x1a\x2a\xf7\xa7\x85\x91\x5e\x16\x8e\xeb\xca\xc4\x70\x98\x2a\x34\x76\x53\xad\xcc\xbf\xd3\xf6\xdc\x0f\x59\x3b\x51\xb9\xe5\x83\x36\xd2\xe3\x36\x11\xb0\xd1\xae\x37\x47\xda\x7b\xf1\x27\xed\xc3\xa7\x4a\xc3\x6f\x33\xb2\x9d\x0f\xae\x39\x8c\x3c\x06\x52\x1c\xa8\xdc\x4e\x58\xfb\x74\x14\x04\xbb\x51\x37\x93\x0e\x1e\xdb\x5e\x96\xdb\xe7\x87\x0e\x64\x78\x5f\xbd\x3a\xfd\xe4\x23\xf4\xa5\x56\x45\xfe\x43\xe3\xe4\x64\xef\xfc\xfb\xdf\xd5\x7e\xff\xf7\xe6\x9f\x2c\xe9\x0e\x4e\x88\xc0\xfc\x73\x15\x2f\xd6\x04\x1b\xd4\x56\xc4\x68\xe0\xc6\xad\x6e\x95\x86\xb5\xd2\xe8\x4f\x83\xe7\xb1\xca\x8a\xb5\x34\x21\x4f\xb9\x2c\xb1\x96\x4a\x2d\x4a\xa7\x84\xcf\x26\xa2\xe5\x52\xe3\x92\xcf\x4e\x0b\x19\x13\x3a\xcc\x8c\xab\x0b\x7b\xf4\x0f\x25\x24\x4c\xbe\xe1\xbd\xa9\x05\xa7\x30\x9e\xc1\x98\xd7\x25\xd5\x09\x47\x86\x12\xce\xdc\x3c\xd1\xb8\xdb\x02\x2f\xe1\x2c\x25\x03\x85\x4c\xf0\xae\xfe\xf6\x8a\xbe\xce\xe7\xae\x98\x45\xeb\x3c\xc3\x0b\xf7\xc8\x13\xd6\x0d\x30\x85\xb8\x23\xfe\xf9\xdc\xc5\x22\x0d\x3f\xf1\x2b\xd6\x50\x9e\x0e\xa7\xd5\x2c\xee\xf7\xa6\xcc\xe7\x68\x09\xbb\xdd\xef\xdc\xd6\xcd\xc1\x68\x72\xf1\xfb\x1f\x46\xc9\x8b\xb1\x9b\x60\xa8\xb5\xb0\xb8\xce\xed\xfd\x98\xc5\xfc\x68\x02\x7f\x0c\xd6\x73\x25\xc1\x25\xf2\x64\x1a\xb2\x56\x1f\x86\xce\x1c\xd9\x8d\xe2\xad\x92\xc6\x46\xd2\x12\x90\x9d\xfc\x55\xe9\x36\x6e\x91\x7f\x5b\xd6\x93\x99\xa9\x17\x69\xcc\xaa\x37\x53\x1a\x4e\x03\x34\x03\x73\xad\x1c\x15\x87\x1d\x1c\x0b\xcf\xca\x2b\x01\x61\x18\xba\x37\x3e\xb5\xf6\x30\xe8\xf2\xcb\x81\xa9\x4c\xaf\x96\xc0\xf1\x14\xe3\x06\xa1\xef\xee\x12\xda\xe5\x80\x3f\xec\xca\xf1\xb8\x33\x4c\xd7\xa4\x45\xbb\x3d\xdb\x1f\x2d\x09\x1f\x8b\xaa\x6a\xb2\x9a\x91\x4f\x2e\xc3\xcb\x97\x41\xd9\xe5\x56\x3a\x55\x72\xb9\xc7\x9e\x0c\x82\x54\xab\x75\x77\xce\xfe\x77\x06\xfe\xa9\x88\x3e\xb0\xe8\x3b\x04\xe8\x67\x40\xab\xef\x71\x10\x58\xf7\x63\xea\xd0\xea\xde\x29\x5d\x01\xb6\x2d\x74\x1c\xb1\xa5\x8a\xd3\x40\x5b\xb5\x7a\x32\x6e\x4b\x4d\x1e\xba\xad\x63\x62\x6f\xc9\xb8\x76\xdb\xd8\x47\x66\x5c\x72\xc8\x68\xd0\x31\x71\xf7\x12\x4f\xff\xf1\x70\xe3\xf8\x97\xaf\x10\x70\x5a\xdd\xd4\x13\x80\xea\x8a\x9b\xe3\x86\x8f\xbd\x17\xc1\x5a\xb4\x51\xdd\x06\x6b\xf3\x4d\xcf\x95\x30\x16\x79\x79\x73\x3f\xf4\x4a\x58\x5b\x65\xf7\x5e\x98\x8f\x6b\x7d\xd7\x2b\x95\x06\x00\xe0\xcb\xd7\x8a\x91\x9f\x76\x1f\xa9\xda\x06\xaa\xf4\xb9\x1b\x24\x35\x57\x94\x15\x53\x28\x59\x17\xd7\xf2\x4e\x49\x65\x71\x67\x17\x60\xdf\xc3\x65\xfe\xb4\x2c\x9e\xd6\xdd\x4e\xc8\xb2\x30\x0c\xaf\xea\x02\x7d\x88\xe6\xfb\xd4\x87\xd4\x7c\xef\xe2\x49\x9f\xc4\x0c\x52\xd9\xbd\xad\xd4\x96\xf4\x1e\x21\x8a\x20\x85\x99\xf0\x1b\x63\xfb\xc6\xf2\x2a\xcb\x90\x0c\xdf\xb0\x44\x53\x64\x5c\xa7\x55\xc3\x77\x9b\x28\x2b\xf0\x11\x5e\x29\xd9\xa9\xbd\x86\x9d\xc1\xc6\x85\x3a\x8d\x62\xdc\xee\xa6\x7e\x8d\xbc\x7d\xd0\x9c\x76\x12\xd7\xd4\xb7\x99\x36\x4c\xad\x17\xe4\xf4\x74\xc2\x7a\xfc\x04\x9b\x7a\x17\xe6\x1d\xa3\xb6\xed\xcd\xbd\x8e\x45\x4d\x13\x3a\xdb\x77\xfb\x4b\x74\x97\xf0\x8d\xab\x40\xd6\x33\xcd\x5a\x58\xb1\x69\x2c\x7e\xd2\x66\xa9\xb5\x54\x66\xdd\x9e\xa9\x5f\xf6\x38\x91\xdd\xae\x5a\xd9\xf7\x6c\x75\x53\x7d\x71\xa5\xb6\x84\x4a\x58\xce\x57\x25\xad\xbe\xb3\x4c\xdd\xd2\x8c\x75\x55\x96\x60\x5a\xf5\x57\xa8\x62\xf6\xa4\xda\xcd\x49\xbf\xb7\x42\x19\xe8\xe2\x72\x8c\x0f\xee\xb4\xda\xd6\x16\x6b\xe3\xaa\x47\x4f\xce\x30\xff\x4c\xe1\x1f\xf0\xda\xad\x33\x5a\x7b\xa3\x4a\x9b\xf0\x03\xde\x4e\xc6\xf5\xb4\xf0\xa2\x8f\xda\xc2\xca\x7d\xc2\xf0\x59\x56\x14\xaf\x04\x6e\xa2\x9b\x0c\x9d\x3b\x58\x9e\xdc\xc1\xb3\x16\xbb\x8a\x24\xbc\x76\x8e\x18\x97\x2b\x9a\x72\x86\x51\x1a\xe1\x86\x3e\x0c\x26\xe7\x3d\x38\xe9\xee\xf3\x06\x8d\x3b\x45\x1b\x7f\x86\xba\x1b\xed\x85\xbf\xce\x92\xf2\xcd\xd1\x4c\x79\x7c\x1c\x1f\xdc\x03\xb6\xe5\xa2\x72\x33\x7b\xd0\x09\x4d\x50\x4c\x6b\x9f\x35\x1d\xd1\xcc\x98\x3d\x1f\xb4\xee\x54\x3d\x54\xe2\xdb\x65\xf3\x58\x61\x67\xf9\xc7\x16\x76\x37\xef\xe8\xa9\xeb\xee\x43\x7f\x61\x6f\x4f\xaf\xaa\xca\xde\x99\x9c\xf5\x94\x76\xdf\xa3\xaf\xc7\x3e\xed\x07\x94\xf8\x8e\xee\x01\x35\xbe\xaf\x9e\xb3\xd6\x13\x2a\x7a\x6f\x01\xab\x66\x9c\x8f\x2f\x60\x2d\x07\x97\x10\x6e\x9b\xf9\xc4\x12\xd6\xe9\xe5\xbf\x5d\xc3\x4e\x32\xeb\x91\x55\xac\x6b\xd4\xdf\xbe\x8c\x55\x2b\x85\x83\x65\xcc\x49\x10\x71\xf7\x57\xae\xc1\x8e\x7d\x72\xed\xea\xba\xf7\xd1\xc5\xab\x3d\xba\xa3\xd5\xab\xf6\xc2\x13\xca\xd7\x43\xf8\xf8\x9b\xd4\xaf\x93\xa3\xf9\x98\x0a\xd6\x9f\xfc\x7f\x41\x09\xeb\x14\x88\x63\x35\xcc\xf8\xed\x97\x47\x14\xb1\xf2\xef\x7f\x02\x00\x00\xff\xff\xc6\x62\x81\xd8\x34\x36\x00\x00") func templateBuilderQueryTmplBytes() ([]byte, error) { return bindataRead( @@ -195,12 +219,12 @@ func templateBuilderQueryTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/query.tmpl", size: 13795, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/query.tmpl", size: 13876, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateBuilderSetterTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x57\xcd\x8e\xdb\x36\x10\x3e\x4b\x4f\x31\x15\xdc\x42\x72\xb3\x74\x92\x5b\x0b\xf8\xb0\x8d\x13\xc0\x40\x9b\x1c\x9c\x3d\x2d\x16\x85\x56\x1c\x79\xd9\x68\x49\x85\xa4\xdc\x2e\x5c\xbd\x7b\xc1\x3f\x49\x96\x65\xaf\x37\x6d\x6f\x36\x39\xff\xf3\xcd\xc7\xd1\x7e\xbf\x98\xc7\xef\x44\xfd\x24\xd9\xf6\x41\xc3\xdb\xd7\x6f\x7e\xba\xaa\x25\x2a\xe4\x1a\x3e\xe4\x05\xde\x0b\xf1\x05\xd6\xbc\x20\x70\x5d\x55\x60\x85\x14\x98\x7b\xb9\x43\x4a\xe2\xcf\x0f\x4c\x81\x12\x8d\x2c\x10\x0a\x41\x11\x98\x82\x8a\x15\xc8\x15\x52\x68\x38\x45\x09\xfa\x01\xe1\xba\xce\x8b\x07\x84\xb7\xe4\x75\xb8\x85\x52\x34\x9c\xc6\x8c\xdb\xfb\x5f\xd7\xef\xde\x7f\xdc\xbc\x87\x92\x55\x08\xfe\x4c\x0a\xa1\x81\x32\x89\x85\x16\xf2\x09\x44\x09\x7a\xe0\x4c\x4b\x44\x12\xcf\x17\x6d\x1b\xc7\xfb\x3d\x50\x2c\x19\x47\x48\x14\x6a\x8d\x32\x81\xb6\x35\xa7\xb3\xfb\x86\x55\x26\x86\x9f\x97\x50\xe7\xaa\xc8\x2b\x98\x91\x4d\x21\x6a\x24\xbf\xf8\x1b\x2f\x28\xb1\x40\xb6\x73\x92\xdd\xef\x4e\xdd\x0b\x95\x0c\x2b\xaa\x8c\xc8\x8c\x7c\x70\xbf\xfd\x4d\x53\xd3\x5c\x3b\xed\x32\xaf\x14\xba\xf3\x2b\x60\x25\x08\x09\xe9\x43\xae\x36\x4d\x59\xb2\xbf\x7a\x93\xc9\x8d\x55\x49\xb2\x73\xb7\x9f\xb8\x11\x68\xdb\x38\x1a\x3a\x59\x82\x96\x0d\x76\xc7\x3e\x2a\x13\xd4\x6f\x8d\xce\xef\x2b\x1c\xc6\x76\x05\x68\xe2\x61\x25\xcc\xc8\x7a\x45\x6e\x14\xca\x95\xad\x15\x3d\x36\x90\xd7\x35\x72\xda\x1d\x18\x85\xce\x08\xb7\xf2\x26\x59\x99\xf3\x2d\xc2\xec\xf7\x57\x30\x2b\x6d\x2d\xca\xce\x9d\x35\x57\x1f\xd6\xb0\x24\x9f\x9f\x6a\x24\x1b\x2d\x19\xdf\xf6\x3e\x1b\x5e\xd8\xae\x48\xc6\x35\x24\x1b\xd4\x89\x11\xdd\x68\xd9\x14\xda\xc6\x6f\x45\x17\x0b\xe8\xa4\xdb\x16\x14\x6a\x65\xb1\x61\x0f\xc9\xc7\xfc\xd1\x94\x01\x6c\x00\x24\x8e\xac\x58\x7a\xd0\xce\xb6\x85\xf9\x10\x08\x6d\x9b\x0d\x2d\xa6\x2e\xe0\xb6\xf5\x16\x4d\xa8\x56\x66\xa4\x04\xfb\x38\x8a\x46\x86\x89\x53\xf1\x40\x0a\x31\xc3\x12\x7e\x08\x46\xad\xce\x15\x2c\xe6\x26\x70\x6d\xd2\xe7\xcd\x23\x4a\x56\x80\x36\x7e\xc4\x0e\xa5\x64\x14\xa1\x96\xb8\x63\xa2\x51\x50\xe4\x55\xa5\x40\x0b\xb8\xa6\x94\x80\x05\xb7\x33\xc1\x4a\xc8\x6d\x67\x5c\x31\x3f\x7a\x33\x1d\x24\xac\xe0\x51\x80\x39\xa5\xa7\x62\xe4\xac\xf2\xa6\x7d\x67\xa3\x48\xa2\x6e\x24\x87\x91\x91\x38\x6a\x63\xd3\xb2\xc5\x1c\xf2\x9d\x60\x14\xb6\xc8\x51\xba\x64\x58\x55\x19\xb8\x81\x1b\x3a\x05\xa5\x90\xfd\xa1\x49\x51\x85\x24\xf6\xfb\x90\x42\xca\x85\xee\xf3\xf0\xc2\x19\xa4\xc2\x42\xe5\x53\xad\x99\xe0\x66\x4c\x4b\xb2\xc2\x32\x6f\x2a\x9d\x39\x95\xd4\xe6\x1f\xf2\x9d\x95\xc4\x4d\x48\x10\xca\x42\xb9\x61\x16\x22\xf8\x70\x04\xb1\xe0\x6e\x12\x6a\x01\x6b\x07\xea\xcf\x60\xce\x24\x65\xae\xb6\x6c\x87\x1c\x76\x79\xd5\x58\x02\x34\xf1\x72\x56\x91\x38\x7a\x09\x24\x47\x8e\x7b\x68\xce\x2f\xc0\x66\xc4\x4a\xe8\x14\xbe\xb3\xfd\x75\xe7\xd3\xa8\xf5\x2e\xe6\x41\x25\x33\xa2\x16\x43\xa7\x50\x10\xb9\x2e\x06\x1e\x18\x74\xf4\x3c\x28\x27\x86\xfd\x9a\xd2\xb3\x1d\x08\xd3\x9e\x53\xaa\xfa\xa4\xb4\x38\xec\xc0\x0b\xab\xfb\x2d\x03\x1f\x8a\x7a\xd9\x4c\x9d\x2b\xfa\x99\x49\x1c\xb2\x45\xd4\x3a\xb6\x76\x46\xe6\x17\x5b\xf9\x71\x09\x07\x56\xbe\xb9\x91\xfd\xfc\x3d\xd7\xc4\x77\x15\xe6\xf2\xa2\x36\x16\x46\xd2\x8d\x90\x9b\x10\x51\xfe\x27\x9d\x3c\xd1\xb3\x4b\x59\xda\x31\xe0\x91\xb8\x8d\xf6\x94\x8e\x79\x77\x2f\xaf\xed\xa0\xca\x87\xcf\x26\xba\x15\xe2\x3d\xdd\x62\xff\x6c\x0a\xfb\x6e\x26\xb9\x19\x8e\xb6\x75\x5d\x99\x21\xb9\xe1\xec\xab\x7d\xec\xbd\xcc\xd2\xee\x38\x5e\x24\x70\xb7\xb9\x63\x54\x1d\x32\x5e\x1a\x36\x1e\x51\x67\x90\x2a\xc6\xb7\x4d\x95\x4b\x63\xd3\xd6\xfd\x6f\xbf\x11\x65\x90\xac\x57\xea\xb4\xcf\x60\x77\xda\x6c\xf8\xe3\x8c\x5a\x5b\xa3\xd8\x3c\x1a\x82\x19\x3f\x79\xc2\x60\xb5\xe7\x55\xec\x78\x15\xe9\x16\xc3\xac\xa3\x27\x16\x7f\x75\xff\x04\x8c\xba\x20\xed\x23\x32\x08\x54\x75\x0e\x5f\xb6\x06\xf4\x51\xa5\xc7\xd9\x5b\x67\xe8\xb6\x39\x46\x15\x10\x42\x3a\x37\xc3\xf8\xd6\xab\xf3\x34\x32\xc1\x22\x4e\xfb\x1c\x85\x5c\xa8\x01\x8f\xf9\x17\x4c\x1f\xf3\xfa\x76\x32\xa0\x3b\x65\x87\x73\x6f\x09\xde\x4f\xf2\x41\x96\x57\xd3\x9b\xc3\xa4\xb7\x5b\x46\xef\x60\x09\xc1\xe4\x3e\x2c\x27\xb6\x44\xde\x90\x59\x01\x98\x5d\x00\x2d\xdc\x4d\xd9\x4e\x3f\x43\x53\x1e\xd4\x2d\xbb\x3b\xf2\x12\xb5\x97\x2f\x2b\x43\x42\xeb\xd2\x9c\x61\x4f\x6d\x47\x8b\xc2\x7a\xa5\xce\xee\x0a\x78\x40\x71\x1e\xe1\xc7\x0b\x43\x30\x33\xde\x19\x2e\xc7\xf6\xff\xb2\x4e\xf4\x61\xa5\x8c\x3a\xd1\x0b\x71\x6b\x80\xcb\xe8\xe9\x6d\xc2\xe2\x6f\xaa\xaf\x83\xa9\x9a\x33\xfa\xd2\xdd\xa2\xff\x88\xa8\xc4\x9f\x28\x21\xb5\x4d\x29\x21\xf9\x9e\xbc\x51\xc9\x41\xe5\xba\x6f\x23\x56\x02\x7e\x35\x5a\x07\x75\x71\x86\x96\x90\xec\x12\xff\x77\xe8\xa2\x3c\xcd\x96\xa3\x96\x4f\x7c\x89\x3c\xcb\x61\xfb\xfd\x98\xa6\x86\x2c\x35\x8d\x82\x7f\xff\x09\x33\x41\x8d\x43\xd6\x9a\x8f\x7c\x9e\xf9\xd2\x99\x62\x89\xe9\xfe\x8d\x5b\x1e\xe2\x21\xeb\x55\x36\xc1\x10\xcc\x7d\x41\x5b\xde\xba\xbd\x9b\x84\xe3\x2b\xa8\x90\x77\x76\xb2\x2c\x30\x94\x25\x96\x84\xf5\x6f\x95\xe9\x39\x73\x52\xee\x7e\x09\xc9\x1f\x83\xf7\x67\x40\x4a\xee\xbe\x6d\x7b\x6e\xea\xeb\x66\x91\x6d\xa8\x27\x08\xdd\x41\xbf\x50\xf5\x87\x64\xbd\x7a\x06\xca\xe3\x52\x30\xaa\x08\x21\xd9\x88\xbc\x86\x9b\x41\xff\xeb\x9f\x00\x00\x00\xff\xff\x15\xb4\xeb\x80\x89\x11\x00\x00") +var _templateBuilderSetterTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x57\xdd\x6f\xdb\x36\x10\x7f\xb6\xfe\x8a\x9b\xe0\x01\xb2\xd1\xd0\x6d\xdf\x36\xc0\x0f\x59\x9d\x00\x06\xb6\x14\x98\x9b\xa7\xa2\x18\x14\xf1\xe8\x70\x55\x48\x95\xa4\xbc\x05\x1a\xff\xf7\x81\x1f\xfa\xb0\xec\x38\x71\xba\xbd\xc9\xbc\x4f\xfe\xee\x77\xbc\x73\xd3\x2c\xe6\xc9\x07\x59\x3d\x2a\xbe\xbd\x37\xf0\xfe\xed\xbb\x9f\x2e\x2a\x85\x1a\x85\x81\xeb\xbc\xc0\x3b\x29\xbf\xc2\x5a\x14\x04\x2e\xcb\x12\xbc\x92\x06\x27\x57\x3b\xa4\x24\xf9\x74\xcf\x35\x68\x59\xab\x02\xa1\x90\x14\x81\x6b\x28\x79\x81\x42\x23\x85\x5a\x50\x54\x60\xee\x11\x2e\xab\xbc\xb8\x47\x78\x4f\xde\xb6\x52\x60\xb2\x16\x34\xe1\xc2\xcb\x7f\x5d\x7f\xb8\xba\xd9\x5c\x01\xe3\x25\x42\x3c\x53\x52\x1a\xa0\x5c\x61\x61\xa4\x7a\x04\xc9\xc0\x0c\x82\x19\x85\x48\x92\xf9\xc2\xda\x24\x69\x1a\xa0\xc8\xb8\x40\x48\x35\x1a\x83\x2a\x05\x6b\xdd\xe9\xf4\xae\xe6\xa5\xcb\xe1\xe7\x25\x54\xb9\x2e\xf2\x12\xa6\x64\x53\xc8\x0a\xc9\x2f\x51\x12\x15\x15\x16\xc8\x77\x41\xb3\xfb\xee\xcc\xa3\x12\xe3\x58\x52\xed\x54\xa6\xe4\x3a\x7c\x47\x49\x5d\xd1\xdc\x04\x6b\x96\x97\x1a\xc3\xf9\x05\x70\x06\x52\x41\x76\x9f\xeb\x4d\xcd\x18\xff\xbb\x77\x99\xde\x7a\x93\x74\x76\x4a\xfa\x51\x38\x05\x6b\x93\xc9\x30\xc8\x12\x8c\xaa\xb1\x3b\x8e\x59\xb9\xa4\x7e\xab\x4d\x7e\x57\xe2\x30\xb7\x0b\x40\x97\x0f\x67\x30\x25\xeb\x15\xb9\xd5\xa8\x56\x1e\x2b\x7a\xe8\x20\xaf\x2a\x14\xb4\x3b\x70\x06\x9d\x13\xe1\xf5\xdd\x65\x55\x2e\xb6\x08\xd3\x3f\xde\xc0\x94\x79\x2c\x58\x17\xce\xbb\xab\xf6\x31\x64\xe4\xd3\x63\x85\x64\x63\x14\x17\xdb\x3e\x66\x2d\x0a\x5f\x15\xc5\x85\x81\x74\x83\x26\x75\xaa\x1b\xa3\xea\xc2\xf8\xfc\xbd\xea\x62\x01\x9d\xb6\xb5\xa0\xd1\x68\xcf\x0d\x7f\x48\x6e\xf2\x07\x07\x03\xf8\x04\x48\x32\xf1\x6a\xd9\x5e\x39\xad\x85\xf9\x90\x08\xd6\xce\x86\x1e\xb3\x90\xb0\xb5\xd1\xa3\x4b\xd5\xeb\x8c\x8c\xa0\x49\x26\x13\x87\xc3\x62\xee\x92\x30\xee\x2a\xa2\x7e\x40\xc5\x0b\x30\xce\x46\xee\x50\x29\x4e\x11\x2a\x85\x3b\x2e\x6b\x0d\x45\x5e\x96\x1a\x8c\x84\x4b\x4a\x09\x78\xa2\x06\x17\x9c\x41\xee\x51\x0e\xc0\xdc\x44\x37\x5d\x79\xbd\xe2\x64\x74\x0b\xf2\x50\x9b\xdc\x70\x29\x48\xd3\xb4\xa0\xfd\x8e\xfa\x28\x6c\xd9\x2c\x46\x8a\x45\x3b\xed\xec\x00\x0a\x67\xad\xd0\xd4\x4a\xc0\xc8\x2e\x99\xd8\xc4\x95\x6f\x31\x87\x7c\x27\x39\x85\x2d\x0a\x54\x01\x0c\x5e\x96\x8e\x7a\x10\x1a\x50\x03\x93\xaa\x3f\x74\x10\xe9\x16\x84\xa6\x69\x21\xc8\x84\x34\x3d\x0e\x51\x79\x06\x99\xf4\xb4\xf9\x58\xb9\x14\x5d\xcb\x32\xb2\x42\x96\xd7\xa5\x99\x05\x93\xcc\xe3\xd7\xe2\x35\x65\x24\x74\x4b\xab\x34\xeb\x2f\xdd\x66\x70\x7d\x40\xb7\x36\xdc\x51\xda\xb5\xbc\xdb\x33\x7f\x86\x7f\xee\x52\x4e\xb4\xe5\x3b\x14\xb0\xcb\xcb\xda\x3f\x86\x2e\x5f\xc1\x4b\x92\x4c\xce\xa1\xe7\x28\x70\x4f\xd3\xf9\x0b\x78\x3a\xe1\x0c\x3a\x83\x1f\x96\x2e\x7c\x38\x3f\xe0\xc1\xb0\xfc\xf3\x61\xfd\x27\x9e\x83\x4f\xb1\x60\x12\xaa\xd8\xbe\x09\x83\x8a\x9e\x26\xf5\x91\xc6\xbf\xa4\xf4\x64\x05\xda\xce\xcf\x29\xd5\xfd\xa5\x8c\xdc\xaf\xc0\x99\xe8\xbe\xa6\xf9\xcf\xef\xa1\xd7\xc1\xd7\xb3\xfe\x39\xe8\x3e\x94\x98\xab\x17\x81\x57\x38\xcd\x40\xdc\xc0\x4b\xc9\xfe\x13\xfc\xbe\x07\xa9\x33\x10\x1a\x60\xb5\x3f\x7e\x30\x8c\xe2\x2b\xba\xc5\x7e\xfc\x48\x3f\x7f\xd2\xdc\x11\xcb\xda\x80\xed\x14\xc9\xad\xe0\xdf\xfc\xd0\x8c\x3a\x4b\xbf\x2b\x44\x95\xf6\xa1\x74\x32\x4e\xf5\xfe\x6b\x91\xb5\x9b\x83\xac\x66\x90\x69\x2e\xb6\x75\x99\x2b\xe7\xd3\xa3\xf7\x4f\xdc\x2c\x66\x90\xae\x57\xfa\xe9\x98\xad\xdf\xe3\x6e\xdb\x1f\xc1\xa9\xf7\x35\xca\x2d\xd6\xb4\x75\x13\x59\x2b\x1d\xdb\xfa\x37\x09\xbb\x37\x09\xe9\x16\xdb\x3e\xc1\xd8\x94\x51\x74\xf7\x08\x9c\x86\x24\xfd\x03\x3c\x48\x54\x77\x01\xcf\x1b\xa7\x7d\x56\xd9\xe1\xed\x7d\x30\x0c\x5b\x11\xa7\x1a\x08\x21\x5d\x98\x61\x7e\xeb\xd5\x73\xf3\xf7\x04\xaf\x5e\x9d\xc1\xe9\x71\x37\x6c\xce\xce\xe1\x14\xfb\x36\x3d\x18\x35\xeb\x95\x3e\x39\x6d\x70\xaf\x5d\x63\x9d\x0f\x47\x4e\xeb\x66\x3c\x75\x5e\x5e\xe1\xff\x65\x20\xf5\x69\x65\x9c\x06\xd5\x17\x56\xcf\x4d\x25\x4e\x9f\x9e\x47\xd6\xc2\x72\x5c\x81\x71\x65\xe7\x9c\x9e\x3b\x9d\xfa\x95\xb4\x94\x7f\xa1\x82\xcc\x17\x85\x41\xfa\x23\x79\xa7\xd3\x3d\xe4\xba\x4d\x9b\x33\xc0\x6f\xce\x6a\x0f\x97\xe0\x68\x09\xe9\x2e\x8d\x3f\x87\x21\xd8\xd3\x6f\xc6\xa8\xe4\x47\xf6\xda\x67\x3b\xb9\x69\xc6\xcd\x3a\xec\xd5\xe3\x2c\xf8\xfe\x85\xf8\xc8\x03\x31\xec\x9c\xf9\x28\xe6\x89\xbe\xdd\xeb\xc7\x0b\x7b\xa2\x7e\x47\x9a\xd9\xe7\x43\xd6\xab\x6e\xad\x75\x8d\x1c\x9d\xf0\xf0\x7f\xec\x21\xff\x8a\xd9\xe7\x2f\x47\xe9\xf8\x06\x4a\x14\xfd\x64\x9e\xb5\x23\x8a\xfb\x39\xc1\xfb\x17\xdb\xd5\x9c\x07\xad\x20\x5f\x42\xfa\xe7\xe0\x15\x8e\x21\xdd\x66\x1b\xe4\xd6\xfa\xbf\x3a\x7e\x20\xf5\xb8\x79\x66\x73\xaa\x3f\xb7\x4a\x5f\x22\xb1\x9d\xb8\x3f\x24\xeb\xd5\x33\x54\x1e\x43\xc1\xa9\x26\x84\x8c\x97\xfb\xe1\x7c\xec\xbf\xfe\x0d\x00\x00\xff\xff\x2b\x26\xdd\x47\xd7\x0f\x00\x00") func templateBuilderSetterTmplBytes() ([]byte, error) { return bindataRead( @@ -215,12 +239,12 @@ func templateBuilderSetterTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/setter.tmpl", size: 4489, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/setter.tmpl", size: 4055, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateBuilderUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x59\x6d\x6f\xe3\xb8\x11\xfe\x2c\xfd\x8a\x39\xc1\x1b\x58\x41\x22\xef\xee\xb7\x6e\xe1\x02\xd7\xdd\x2c\x10\xa0\xc8\x15\x9b\xbd\xeb\xa1\xb9\xe0\x40\x8b\x23\x9b\x8d\x44\x6a\x49\xca\x49\xea\xea\xbf\x17\x7c\xd1\x9b\xa5\x38\xce\x21\x68\xb1\x9f\x62\x89\xe4\x70\xe6\x99\x99\x67\x66\x94\xdd\x6e\x71\x1a\x7e\x14\xe5\xa3\x64\xeb\x8d\x86\xf7\x6f\xdf\xfd\xe9\xbc\x94\xa8\x90\x6b\xf8\x4c\x52\x5c\x09\x71\x07\x97\x3c\x4d\xe0\xc7\x3c\x07\xbb\x49\x81\x59\x97\x5b\xa4\x49\xf8\x75\xc3\x14\x28\x51\xc9\x14\x21\x15\x14\x81\x29\xc8\x59\x8a\x5c\x21\x85\x8a\x53\x94\xa0\x37\x08\x3f\x96\x24\xdd\x20\xbc\x4f\xde\x36\xab\x90\x89\x8a\xd3\x90\x71\xbb\xfe\xb7\xcb\x8f\x17\x57\xd7\x17\x90\xb1\x1c\xc1\xbf\x93\x42\x68\xa0\x4c\x62\xaa\x85\x7c\x04\x91\x81\xee\x5d\xa6\x25\x62\x12\x9e\x2e\xea\x3a\x0c\x77\x3b\xa0\x98\x31\x8e\x10\x55\x25\x25\x1a\x23\xa8\x6b\xf3\x76\x56\xde\xad\xe1\xc3\x12\x56\x44\x21\xcc\x92\x8f\x82\x67\x6c\x9d\xfc\x9d\xa4\x77\x64\x8d\xe0\x8f\x6a\x2c\xca\x9c\x68\x84\x68\x83\x84\xa2\x8c\x60\x36\x5e\x62\x45\x29\xa4\xee\x2d\xcd\x56\x15\xcb\x8d\x79\x1f\x96\x50\x4a\xc6\x35\xcc\x4b\xa2\x52\x92\xc3\x2c\xb9\x22\x05\xc6\x10\xfd\x3c\xd4\x45\x62\x8a\x6c\xeb\x4e\xb4\xbf\x5b\x31\x46\xec\x62\x01\x7d\xc9\x75\x6d\xd0\x34\x50\x34\x6f\x32\x21\xc1\x5a\xc8\xf8\xda\x6e\xb5\x57\x99\x8d\xc8\x35\xd3\x0c\x55\x12\xea\xc7\x12\xf7\xc5\x28\x2d\xab\x54\xc3\x2e\x0c\x52\x0b\x41\x18\xec\x76\xe7\x3d\xeb\x1c\x6a\x8b\x8c\x61\x4e\x95\x31\xf2\xbc\xae\xc3\xa0\x94\x48\x59\x4a\x34\x2a\xb8\xb9\x6d\x1f\x92\xfe\xbd\xa1\xd3\xfa\x1f\x1b\x94\x08\x84\x52\x05\x04\x38\xde\x43\xbb\xdb\xaa\xdc\x33\x21\x09\xb3\x8a\xa7\x30\xef\x03\x52\xd7\x70\x3a\x54\x38\x76\x12\xe7\xa5\x82\x24\x49\xa6\xaf\x8e\xf7\x0f\x19\xf3\x86\x62\x93\x9e\x05\x4b\x20\x65\x89\x9c\xce\x9f\xdc\x72\x06\xa5\x4a\x92\x24\x0e\x03\x89\xba\x92\x1c\x06\x4e\x73\xb6\xee\x76\x70\xcf\xf4\x06\xf0\x41\x23\xa7\x30\x83\xe8\xaf\xee\xfe\x68\xe0\xc9\x60\x10\x3b\x0a\xb5\x36\x3b\x12\x1f\x09\xe6\x64\xfd\x47\x85\x79\x57\x21\x5d\xa3\x1a\x8b\x5c\x2c\xe0\x9a\x6c\x11\xf0\x01\xd3\xca\x98\x6d\xa0\xff\x56\xa1\x7c\x04\xc2\x29\x38\xc3\xdc\x5b\x5e\x15\x2b\x94\x26\xad\xa4\xb8\x57\x8b\x2d\x4a\xcd\x52\x54\x50\x10\x9d\x6e\x90\xc2\xea\xd1\xe5\x9b\x28\x51\x12\xcd\x04\x9f\x72\x1d\x4c\xf9\xce\x68\x30\x4f\xf5\x03\xa4\x82\x6b\x7c\xd0\x26\xef\xcc\xdf\x18\xe6\x8c\xeb\x33\x40\x29\x85\x8c\xbd\xbb\xf6\x10\xf8\xe2\x05\x47\xbd\x3b\x22\x9f\xb0\x91\xcb\xe7\xe8\x9f\x28\xc5\x2f\x24\xaf\x30\x82\xb7\x2e\x52\x27\x21\x52\x64\x8b\x1e\x21\x1b\xee\xe6\x06\xbb\x7b\xda\xbd\x2e\xb8\xae\xb5\x90\x8e\x1b\x1a\x2b\xe2\xb0\xc3\xf5\x57\x47\x6f\x77\x68\x9f\xce\x60\x55\x69\x28\x09\x67\xa9\x02\x96\x01\xe1\xce\x34\x10\x69\x5a\x49\xf5\x22\xbc\x7e\x9d\x06\xcc\xf0\xca\x2e\x0c\x48\x96\x61\xaa\x91\x5a\xec\x0c\x7f\xec\xeb\xde\x29\x1b\xb0\xcc\x6e\xfa\x61\x09\x9c\xe5\xe6\x70\x60\x35\x9c\xa3\x94\x71\x18\x74\xe6\x37\x32\xbd\x79\x17\x0f\x98\x4e\x84\xcd\xd1\x46\x98\xf3\xd3\x36\x38\x4c\x76\x61\xf0\xfb\x31\xea\x7b\xed\x50\xca\x9e\x62\x1d\xee\xe6\xe9\xb5\x70\xb7\x92\xa7\x75\xde\xb5\x38\x4e\x68\xdb\x98\x1a\xff\xf9\x30\xd2\x47\xa6\xf8\x5e\x78\xfb\x8c\x9f\xe9\xa2\xcc\xdb\xe2\x92\x41\x44\x19\xc9\x31\xd5\x8b\x37\x6a\xd1\x14\xb9\x7e\xb8\xda\x43\x0f\x6d\x12\xb8\xe3\x13\x8c\x33\x13\x1c\xf7\x4b\x57\x06\xd1\x1b\xf5\x13\xc7\x21\xef\x0c\xcc\xee\x97\xac\x9e\x84\x5e\xd5\x1a\xbc\x3d\x58\xb8\x08\x28\xc6\xd7\x39\x4e\x54\xb0\xc7\x5e\xfd\x1a\x0a\x1c\x97\x30\x46\x9d\x80\xcb\x4f\xc9\x57\x73\xa6\xc9\xf3\x03\x65\xed\x79\x12\x1f\xda\x76\x1c\x8f\xff\x61\x81\xaf\xc6\xe5\x4e\x10\x6d\x31\x3c\x90\x00\x43\x54\x0f\x92\xf5\x69\xdf\x3f\xaf\x4a\xdb\x11\x67\x79\xf4\xbd\x52\xf7\x00\xc1\x83\xec\x3d\x00\xb0\x69\x4f\x92\x2f\x9d\xc0\xd7\xe4\xf3\x7d\xd9\x87\x79\x1d\x84\x6b\xb2\x5f\x1a\x31\xdf\x0d\xd1\x4f\x68\xfd\x7f\xe4\xfa\x9e\x36\xff\x5b\xba\xef\x7e\x2e\x4e\x41\x6d\x88\x44\xda\x50\xa9\xa3\x45\x58\xa1\xbe\x47\x74\xd1\xa0\xef\x85\xe7\x12\xa9\xc0\xce\x56\xa3\xd1\xaa\x61\x53\xb7\x26\x09\x5f\x23\xcc\x7e\x3f\x83\x59\x66\xb4\x9f\x25\x9f\x9d\xd4\x26\x73\x59\x06\x42\xc2\x9c\x0b\x0d\xb3\x2c\xb9\x2c\x8a\x4a\x93\x55\x8e\xb1\x79\x72\xf3\xd1\x27\xcc\x48\x95\x6b\xf0\x64\x70\x6e\x56\x3c\x70\x56\x56\xeb\xd1\xac\xa3\xf9\x46\xb4\x7f\x97\x5c\x55\x05\x4a\x96\xba\xb5\x80\x50\xea\xf6\x1f\x25\xc6\x23\x34\xfa\xed\xc4\xff\x54\x9a\xd6\x97\xe4\x6e\x7f\x9a\x23\x91\xd3\xb2\x57\x42\xe4\x03\x21\x1d\xf8\xe6\x65\x0f\x28\x74\x40\x5d\x18\xd6\x6f\x6f\x9b\xe1\x48\x62\x41\xca\x1b\x73\x17\x3a\x1b\xbb\x32\x77\xeb\x1c\xb8\x7b\xf1\x1d\xa5\x79\x1b\x49\x2c\xc4\x16\xa9\x99\x4b\x77\x3b\x6b\x26\x26\x3f\x73\xf6\xad\x42\xf7\x66\x56\xc2\x12\x22\x6b\x6a\xbb\xab\x0f\x8c\x9b\x76\x67\xa5\x39\x77\x6d\x35\x69\x55\x1e\xcb\x33\xb0\x98\xf3\xb9\x32\x4f\xcf\x9b\xd4\xb7\xa8\xa5\xfd\x27\xe2\xd8\xd6\x4d\xb0\xe6\x90\xfc\xc5\x71\xec\xab\xae\x6f\x74\xfa\x2d\x91\x1b\xe3\x93\xeb\x54\x94\xad\x57\x8e\x1f\xe2\x87\x59\x31\xe1\x88\x7d\x88\x5c\x0d\x9c\x59\x2e\x6b\x3f\x26\x44\x1f\x0d\xfe\xd1\x18\xe3\x30\x08\x7c\xc3\x65\x0f\xd4\x35\x58\x4f\x39\x6a\x77\xd8\xb6\x1d\x15\x5d\x23\x68\x01\x3d\xc4\xfd\x52\x12\x06\xc1\x91\x4d\x72\xef\xa6\xf9\xe4\xc8\x1d\x04\xfb\x9c\xe9\x43\xc7\x5d\xbb\x17\x21\x4b\xd0\xb2\x42\x73\xea\x89\x21\x3b\x08\x1c\x48\x3e\x62\x3c\x38\x36\x72\x73\x71\x8f\x12\xe6\x6d\xcb\x9a\xbc\x53\xd1\xc0\xb2\xb8\x39\xb0\x38\x35\x20\xdb\x29\xd7\x18\x2c\xdc\xef\x92\x48\x52\xa0\x46\x69\x6a\x40\x96\xb3\x54\x2b\xc7\xd8\xf6\x6b\x53\xa3\x83\x3d\x61\x63\x26\xf0\xce\xc2\x6f\x36\xda\xfb\x30\xb5\x69\xb2\x8d\xfc\x63\x93\x21\x56\x5d\x46\xd5\xe7\xa1\x3b\xbf\xd8\xa4\x8b\x60\x6e\x5a\xdf\x2a\x27\xb2\x75\xd4\x7f\x7c\xc0\xc5\x10\x5d\x7e\x72\x01\xd9\xba\xb8\x91\x53\xd7\x2e\xcc\xf1\x65\x6e\x36\x33\x3c\xa3\xea\x85\xde\xee\x2e\x9d\x33\x6a\x3f\xc0\x4c\xa6\xec\x13\xc1\xc0\xb2\x51\x0d\xf5\x84\x33\x1d\x0f\x5d\x41\x1d\x07\xd2\xc1\x83\x50\x90\x3b\x9c\x3f\xcf\x28\xb1\x11\x6d\xeb\x82\x19\x42\x98\x4d\x5c\x9b\x9f\xc6\xb8\x17\xdf\x7b\xc3\xa8\xba\x61\xb7\xb7\xb0\x84\x96\xb2\xea\xf6\x86\x43\x31\x3d\x95\xe4\x4d\x54\x1c\x91\xe5\x8d\xff\xc7\xbe\x57\xaf\x9a\xe3\x2e\xb2\xeb\xda\xf8\xfd\x74\x2c\xf5\x29\xaf\x53\x65\xcc\xb2\x2e\xb9\xb9\x9d\x74\xc8\x19\xe4\xc8\x5b\xf1\x71\xdc\x30\x87\xf5\x48\xc4\xba\x72\x64\xd2\x8d\xb9\x5d\x6e\x7d\x09\xd1\xbf\x7a\x75\xc8\x8d\x0d\xd6\x9b\x6e\xbd\xae\x3b\xa7\xb6\xea\x3b\xcf\x1a\x6f\x35\x9b\x8c\xcf\x9a\xe5\xee\x65\x72\xf9\xe9\x19\xf7\x25\xe3\xa4\x70\x9f\x09\x1b\xa6\x1a\xd7\xfb\xc9\x72\xd5\x36\x6b\xcd\x27\x51\x33\xe5\x40\x81\x7a\x23\x68\x43\x51\xef\x9b\x89\xf9\xc9\xb2\xe5\x46\x23\x5f\xf1\x9b\xef\xdb\xbe\x56\x35\x1f\xb6\xcf\x9b\xe5\x7f\xa3\x14\xbd\xf5\x76\x02\x6b\xcf\xf7\xcb\x99\xdf\xd4\x8e\x10\xe7\xe3\xb6\x62\xd8\xe3\x9d\x0f\x5b\xa5\x61\x3b\xe7\xbc\x34\xc1\x06\xd3\xed\x53\xc3\x03\xbb\x71\xdf\x05\x27\x27\xf0\xc3\x64\x8d\x99\x16\xd5\xc2\xef\x62\x60\xdb\xb4\xf5\xbd\xef\xfe\x5e\x89\x81\xc6\x3e\xc0\x5b\x0d\x2e\xd5\x57\x66\xdf\xcc\xe3\x3e\xbd\x8f\xc8\xe2\x09\x7b\xe0\x64\x3b\x88\x10\x0f\x96\x2b\x38\x66\x7e\x9f\x0b\x69\x0e\xfe\x42\x72\x46\x89\x16\x52\xb9\x4b\x2f\x78\x55\xc4\x53\x0d\xf3\x0b\x01\xed\x4d\x2a\x7b\xe3\xcd\x18\x87\x56\x07\x63\xed\xe9\x51\xf2\xc7\xf3\xd0\x20\x7d\x6c\xe0\x99\x9c\xcf\x0a\x9d\x5c\x98\x99\x2d\x9b\x47\xcd\x3f\x64\xea\xfa\x03\x6c\xdb\x2b\x33\xc2\x72\xa4\x36\x29\xec\x68\x01\xbf\x45\xee\x46\xef\x90\xdf\xa2\x0f\xf0\x66\x1b\xd9\x91\xb2\xe5\xf2\x21\xae\x83\x9f\xcf\xf7\xc1\x83\xfe\xab\x85\xb5\x61\xa7\x7d\xd3\x47\x8d\x79\x0c\x7f\x81\x77\xce\xe4\x29\x8b\xed\x84\xaa\x92\x2b\xbc\x1f\x5a\x5c\x54\xb9\x66\x65\x8e\x40\x94\x62\x6b\x5e\x20\xd7\xca\x4c\xe1\x04\x2a\xa7\x89\xad\xe3\xce\x78\xec\x8c\x8f\xe2\xae\x7c\xb0\x0c\x6c\x5c\x60\x97\x1e\x9e\x0c\x27\xc2\xe2\x50\x17\x76\x72\x32\x19\x45\xe3\x19\x64\xf9\x9c\x7f\x9f\xb2\xd6\xde\xee\x3e\xf6\x3d\x6f\x5e\x63\x5f\x3f\x4f\x26\x7d\xdb\xa4\xe1\x7f\x03\x00\x00\xff\xff\x43\x6c\x58\xbe\xb5\x1c\x00\x00") +var _templateBuilderUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\x6d\x6f\xe3\xb8\x11\xfe\x6c\xfd\x8a\x59\xc1\x7b\x90\x02\x5b\xce\xee\xb7\x66\xe1\x02\x77\xbb\x49\x1b\xa0\xdd\x2b\x36\x7b\xd7\x43\x73\xc1\x82\x96\x46\x36\x1b\x99\xd4\x92\x94\x93\xd4\xd5\x7f\x2f\x86\x94\x68\xc9\x56\x52\x67\x91\xb6\x38\xa0\x40\x80\x48\x22\x39\x9c\x79\xe6\xed\x21\xbd\xdd\xce\x4e\x82\xf7\xb2\x7c\x50\x7c\xb9\x32\xf0\xf6\xf4\xcd\xef\xa6\xa5\x42\x8d\xc2\xc0\x05\x4b\x71\x21\xe5\x2d\x5c\x8a\x34\x81\xef\x8b\x02\xec\x24\x0d\x34\xae\x36\x98\x25\xc1\xe7\x15\xd7\xa0\x65\xa5\x52\x84\x54\x66\x08\x5c\x43\xc1\x53\x14\x1a\x33\xa8\x44\x86\x0a\xcc\x0a\xe1\xfb\x92\xa5\x2b\x84\xb7\xc9\x69\x3b\x0a\xb9\xac\x44\x16\x70\x61\xc7\xff\x74\xf9\xfe\xfc\xe3\xd5\x39\xe4\xbc\x40\x68\xbe\x29\x29\x0d\x64\x5c\x61\x6a\xa4\x7a\x00\x99\x83\xe9\x6c\x66\x14\x62\x12\x9c\xcc\xea\x3a\x08\xb6\x5b\xc8\x30\xe7\x02\x21\xac\xca\x8c\x19\x0c\xa1\xae\xe9\xeb\xb8\xbc\x5d\xc2\xd9\x1c\x16\x4c\x23\x8c\x93\xf7\x52\xe4\x7c\x99\xfc\x85\xa5\xb7\x6c\x89\xd0\x2c\x35\xb8\x2e\x0b\x66\x10\xc2\x15\xb2\x0c\x55\x08\xe3\xc3\x21\xbe\x2e\xa5\x32\xed\x90\x7b\x83\x28\x18\x6d\xb7\x53\x50\x4c\x2c\x11\xc6\x25\x33\x2b\xda\x6c\x9c\x5c\xf1\x45\xc1\xc5\xf2\xd2\xce\xd2\xb4\x62\x34\x0a\xad\x3a\x34\xa5\xae\x43\xb7\x0e\x45\x46\x63\x71\x60\xf7\x1a\x2f\x2a\x5e\x10\x5e\x67\x73\x28\x15\x17\x06\xa2\x92\xe9\x94\x15\x30\x4e\x3e\xb2\x35\xc6\x10\xfe\xd4\x37\x4e\x61\x8a\x7c\xe3\x56\xf8\x67\x2f\xa6\x99\xb4\xae\x0c\x33\x5c\x8a\x9d\xd8\xdd\xba\x30\x69\x47\xad\xcc\x60\x36\x83\xae\x22\x75\x4d\xde\x24\x57\xb4\x5f\x72\xa9\xc0\x22\xcc\xc5\xd2\x4e\xb5\x9a\xd1\x44\x14\x86\x1b\x8e\x3a\x09\xcc\x43\x89\xfb\x62\xb4\x51\x55\x6a\x60\x1b\x8c\x52\xeb\x02\x67\xff\x0e\x5d\xe7\xb5\x59\xce\xb1\xc8\x34\x81\x3c\x25\xcc\x4a\x85\x19\x4f\x99\x41\x0d\xd7\x37\xfe\x25\xe9\xee\x1b\x38\xad\xff\xba\x42\x85\xc0\xb2\x4c\x03\x03\x81\x77\xe0\x67\x5b\x95\x3b\x26\x24\x41\x5e\x89\x14\xa2\x2e\x7e\x75\x0d\x27\x7d\x85\x63\x27\x31\x2a\x35\x24\x49\x32\xbc\x75\xbc\xbf\x88\xcc\xeb\x8b\x4d\x3a\x16\xcc\x81\x95\x25\x8a\x2c\x7a\x74\xca\x04\x4a\x9d\x24\x49\x1c\x8c\x14\x9a\x4a\x09\xe8\xf9\xd8\xd9\xba\xdd\xc2\x1d\x37\x2b\xc0\x7b\x43\xd1\x33\x86\xf0\x07\xb7\x7f\xd8\x73\xfc\xa8\x17\xbb\x1a\x8d\xa1\x19\x49\x13\x13\x4d\xdc\x7d\x9b\xb0\xc6\x55\x98\x2d\x51\x1f\x8a\x9c\xcd\xe0\x8a\x6d\x10\xf0\x1e\xd3\x8a\xcc\x26\xe8\xbf\x56\xa8\x1e\x80\x89\x0c\x9c\x61\xee\xab\xa8\xd6\x0b\x54\x94\xd6\x4a\xde\xe9\xd9\x06\x95\xe1\x29\x6a\x58\x33\x93\xae\x30\x83\xc5\x83\xcb\x77\x59\xa2\xb2\x31\x3a\xe4\x3a\x18\xf2\x1d\x69\x10\xa5\xe6\x1e\x52\x29\x0c\xde\x1b\xca\x7b\xfa\x1f\x43\xc4\x85\x99\x00\x2a\x25\x55\xdc\xb8\x6b\x0f\x81\x4f\x8d\xe0\xb0\x9b\x26\x4d\xc1\x08\x5d\x3d\x09\xff\x86\x4a\xfe\xcc\x8a\x0a\x43\x38\x75\x91\x3a\x08\x91\x66\x1b\x6c\x10\xf2\xe9\x6e\x67\x6f\x98\xa2\xd2\x31\x42\xa5\x9c\x2e\xc1\x68\xc4\xf2\x1c\x53\x83\x19\x70\x61\x82\x51\x1c\x8c\x78\x0e\x05\x8a\x7d\x63\x93\x95\x94\xb7\x3a\x86\xf9\x1c\x4e\xc9\x00\xbf\xce\x5a\x05\xf3\xfd\x98\x71\x11\x7b\x65\xa4\x72\x05\xaf\x85\x26\x0e\x46\x35\x60\xa1\xd1\x0a\x21\x85\xd6\x95\x81\x3f\x53\x35\x90\x24\xc6\x3e\xe1\x45\x25\xd2\x88\x40\x1f\x42\x73\x02\x6b\x37\x8d\x4b\x11\x43\x64\x01\xe9\x62\x3b\x1a\xb5\xc5\x65\x02\xf2\x96\xca\xcf\x3a\x89\xac\xaf\x92\x76\x59\x9b\x49\x34\x99\xe7\xf0\x4a\xde\xba\x85\x6d\x02\x08\x5e\x4c\x20\x5f\x9b\xe4\x9c\xa4\xe6\x51\x58\x09\xbc\x2f\x1d\x4e\xbe\xae\xd9\x7a\xf3\xfa\x73\x38\x81\xb5\x15\x44\xee\x18\xf5\x2a\x5f\x5d\xc3\xdc\xcf\xa7\xd1\x6f\x07\xcd\xab\xd6\x13\x11\x8c\x46\xd6\x08\xaa\x35\x9c\x2c\x7d\xdc\x73\xef\x80\xc3\xef\xe1\xf4\x1d\xf0\xe9\xd4\xa3\x34\xa0\x82\x9d\x7d\xcd\xa7\x6f\x6e\xa2\x75\x65\x48\x38\xd9\xc5\x73\xf8\xe2\x94\x3e\xb3\x16\x39\x24\xad\x72\x13\xd8\xb3\x39\x7e\x67\x27\xbe\x9a\x13\x8c\x6e\xab\x46\xf7\x53\xaf\x74\x40\x7f\x83\x16\xed\x72\xf9\x17\xd7\xd2\x6f\xd1\xbe\x4d\x60\x51\x19\x28\x99\xe0\xa9\x06\x9e\x03\x13\xce\xe5\x20\xd3\xb4\x52\xfa\x59\x39\xfa\xcb\x70\x92\x52\x8f\xda\x06\x7b\x4e\x3a\x3b\x84\xa8\xe3\x16\x9e\xef\xdb\x6a\x35\x8c\x50\xa9\x78\xc8\xc6\xc6\xbc\xf3\x7b\x4c\x07\x4a\xd5\xd1\x46\xd0\xfa\x61\x1b\x1c\x26\xdb\x60\xf4\xe5\x18\xf5\x1b\xed\x76\xb8\x93\xe0\x1d\xee\xf4\xf6\x52\xb8\x5b\xc9\xc3\x3a\x6f\x3d\x8e\x03\xda\xb6\xa6\x1e\x46\x55\x1f\xe9\x23\xdb\xca\x5e\x49\x6d\xba\xcc\xd8\xac\xcb\xc2\x13\x95\x1c\xc2\x8c\xb3\x02\x53\x33\x7b\xad\x67\x2d\xb1\xeb\x26\xa6\x5d\x74\xef\x0b\xaf\x5b\x3e\xd0\xe5\xc6\x52\xe0\x3e\xbb\xca\x21\x7c\xad\x7f\x14\x18\x1e\x30\x26\x6f\x76\x97\x55\x75\x24\xec\x13\xab\xa3\x79\x55\x4f\xc6\x93\xd4\x8a\x81\xe6\x62\x59\xe0\x00\xc7\x7a\xe8\x30\xac\xbe\xc0\x67\x93\xac\x7f\x4f\x29\xfa\x56\x1f\xc7\x2a\xbe\x59\xe0\x8b\x31\x0b\x27\x28\xf3\x78\x3d\x91\x1a\x7d\x04\x9f\xa4\x0e\x27\x5d\x5f\xbc\x28\x89\x08\x05\x2f\xc2\x97\x22\x12\x82\x0e\x61\x3d\x5d\x9f\x43\x27\x68\xf5\xff\xa9\xc4\x33\xa8\xc4\xb7\x01\xb6\x53\xab\x5d\xfe\x1b\xa3\x10\x16\xce\x01\x12\xb1\xb3\xe7\x3f\x41\x20\x7a\xd9\xfa\x24\x87\xe8\x25\x40\x7b\x30\x4b\x3e\xed\x04\xbe\x24\xab\xd8\x97\xfd\x34\xbb\x00\xe9\xae\x37\x9e\x5b\x9d\x7e\x33\x74\x63\x40\xeb\xff\x21\xe3\xe8\x68\xf3\xdf\x25\x1d\xbb\xc7\xd9\x09\xe8\x15\x53\x98\xb5\x2d\xda\xb5\x60\x58\xa0\xb9\x43\x74\xd1\x60\xee\x64\xd3\xb7\x94\x06\x7b\xab\x75\x70\xa9\xd5\x76\x6e\x52\xc1\xe6\x36\x5c\xdf\xfc\x51\xca\xdb\xc0\x57\x47\x18\xac\x89\x8f\x29\x63\x1b\x2d\x28\x5c\xcb\x0d\x2b\x9e\xad\x4c\xd3\xa6\x1b\x32\xd4\x65\x57\xee\xd2\x2a\xb9\x4a\x65\x89\xc9\x0f\x8f\x70\xab\x97\xba\xb2\xda\x6e\xdb\xeb\xb7\x2f\x13\x18\xa3\xbb\x7f\x3b\xb7\x96\x35\xae\xe2\x39\x8c\x31\xf9\x49\xf0\xaf\x95\x73\x9f\x75\xba\x8d\x5f\x2f\x3f\x7c\x5f\x20\xa3\x68\xc1\xe4\xca\xba\xe8\x82\xa0\x76\xb3\x1b\xf2\x66\x17\xd4\x35\xa4\x34\xd3\xa5\x33\x7d\xc6\x1d\x3b\xcb\x96\x08\x46\x36\x5f\x3f\x3f\x94\x7e\x28\xa1\xba\x7e\x1c\x3d\xef\xec\x14\x0d\x5e\x30\x1d\xf4\xa3\xa4\xb7\xa4\x53\xa2\xf7\x6f\x8f\x6c\xa5\xa6\x50\xa0\x56\xed\x71\x28\x6d\xaf\x91\x77\xa8\x20\xf2\xbc\x38\x79\xa3\xc3\x9e\x11\x71\xbb\x60\x76\x42\x78\xda\xeb\x1b\xb2\x4d\xba\xe7\x92\x29\xb6\x46\x83\x8a\x52\x3c\x2f\x78\x6a\xb4\x4b\x48\x7b\x8d\xdb\xea\x60\x57\xd8\x68\x1a\x35\x7e\xc1\xaf\xa4\x40\x0f\x11\xa7\xd3\x1c\xc2\x4d\xd8\xbc\x36\xa1\xeb\xd4\xe5\x99\xbe\xe8\x7b\xee\x13\xc5\x2f\x86\x10\x11\x63\xae\x0a\xa6\xbc\x4f\xfe\xd9\x84\x62\x0c\xe1\xe5\x07\x17\xaa\xde\x9b\xad\x9c\xba\x76\x09\x80\xcf\xf3\x28\x2c\x1e\x80\x67\xfa\x99\x8e\xdd\x6d\x1a\xf1\xcc\xde\x2c\x76\x24\x5f\x7e\xb0\xff\x1f\xbb\x58\x1c\xf6\x7b\x5f\xa2\xbb\x3c\x7c\x3a\x00\x86\x82\xbf\x85\xf0\x88\xe8\x6f\xc1\x3a\x04\x4a\xbf\x68\xec\xbb\x30\xa8\x6b\x02\xe9\xe4\x50\xea\x23\x10\x11\xaa\xc4\x6a\xd8\x2d\x46\xd7\x37\x83\xe0\x4e\x3c\xb1\x22\xf1\x71\xdc\x22\x6b\x39\x57\xc8\x29\x4a\x76\xb1\xc9\xdd\x2c\x37\x3e\x87\xf0\xef\xcd\xb0\x27\xe0\x8e\xaf\xb9\xf1\xba\xb6\x45\xcd\x16\x23\xaf\xbe\xe3\xa0\x3c\xd3\xd7\xed\xa4\x9b\x86\xa9\xd1\xf0\xee\x63\x72\xf9\xc1\x13\xce\x61\xf7\x3d\xee\xef\x26\xad\x5d\x9a\x0c\x3d\xf5\xaa\xbe\x6f\x5c\xed\xc5\x38\x9d\x2e\x60\x8d\x66\x25\xb3\x36\x9f\xdf\xb6\xa7\xd2\x47\xab\xbf\x3b\x92\xd8\xa1\xa9\xff\x95\xa5\x29\xf9\xed\xcf\x2b\xd3\x76\xf8\x1f\xa8\x64\x67\xdc\x9f\x7c\xfc\xfa\x6e\x57\x68\x26\x79\x3a\xe5\xa5\x1c\xdb\x15\xa6\xce\xe2\x69\xb7\x2f\xe4\xae\x2f\x5c\xb8\xbe\x3b\x6d\x0f\x52\xd4\x1a\xf2\xc4\xfd\xaa\xf2\x01\x73\x56\x15\xa6\xf1\xab\x63\xc9\xee\xac\x31\x58\x70\x7d\x93\xfd\x03\x1a\x5b\x79\xdf\xb9\x33\xc7\xb6\x11\xfa\x63\x49\x83\xac\xa0\x20\xf8\xee\x3b\x78\x35\x2c\xa4\x9f\x6e\xb6\x09\x61\x16\xc5\xbb\xb2\xe7\x02\x68\xd3\xaa\xd1\xf9\xe9\xaa\x91\xd0\x53\xbe\xc9\x0e\xaf\xc4\xa5\xfe\xcc\xed\x97\x28\xee\x16\xd2\x83\x52\x72\x85\x66\x48\x9f\x68\xd3\x0f\xaf\x06\x37\x57\xda\xe9\xd0\x1d\x49\x45\xab\x7e\x66\x05\xcf\xe8\xb4\xa7\xdd\xa6\xe7\xa2\x5a\xc7\x10\x09\x69\xec\xfb\x9a\xb6\x5a\x14\x18\xef\xb0\xdd\x3c\x17\xdb\xf6\x38\xd7\xa7\x8b\x87\x70\x78\x55\x9c\xfa\x87\xe7\x97\x6e\x76\xd9\xb8\xa4\x92\xd0\x3d\x17\x6e\xb7\x2d\x3b\x3c\x83\x8d\x97\x96\x33\x5e\x60\x66\x73\xc6\xb2\x30\xf8\x35\x74\x1b\x36\x90\xff\x1a\x9e\xc1\xeb\x4d\x68\xd9\xb7\x3f\x3a\xf6\x91\xeb\x3d\x4e\x8f\x60\x2d\x84\xf0\x8e\xb9\x38\x38\xd1\x07\x56\x7c\x64\xa4\xee\xd7\xf4\xcb\x0f\x84\xe7\x31\x33\x77\xe1\x48\x01\xdc\x7a\x60\x08\x3f\x7b\x34\xd0\xc9\x47\xbc\xeb\xe3\x67\xb9\x92\xbb\xcf\xaa\x9c\x15\xb6\xa5\x3a\xec\x70\x87\x5d\x78\x18\x67\x87\x8f\x75\x1d\xfc\x2b\x00\x00\xff\xff\x22\xa9\x5f\xbf\xac\x1e\x00\x00") func templateBuilderUpdateTmplBytes() ([]byte, error) { return bindataRead( @@ -235,12 +259,12 @@ func templateBuilderUpdateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/update.tmpl", size: 7349, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/update.tmpl", size: 7852, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateClientTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x5d\x6f\xe3\xba\x11\x7d\xb6\x7e\xc5\x54\xc8\xde\x4a\x81\x43\x6d\xf7\xad\x29\xf6\x61\x91\x6c\x2f\x02\xb4\xc9\x6d\x37\x45\xef\xdb\x05\x4d\x8e\x64\x36\x32\xa9\xa5\xa8\xc4\x81\x9b\xff\x5e\x0c\x49\x7d\xd9\x8e\x93\x2e\xda\x97\xc4\x22\xa9\x99\x33\x67\x0e\x87\x23\xee\x76\xc5\x79\x72\x65\x9a\x67\xab\xaa\xb5\x83\x4f\x1f\xff\xf0\xc7\x8b\xc6\x62\x8b\xda\xc1\x9f\xb9\xc0\x95\x31\x0f\x70\xa3\x05\x83\x2f\x75\x0d\x7e\x51\x0b\x34\x6f\x1f\x51\xb2\xe4\x7e\xad\x5a\x68\x4d\x67\x05\x82\x30\x12\x41\xb5\x50\x2b\x81\xba\x45\x09\x9d\x96\x68\xc1\xad\x11\xbe\x34\x5c\xac\x11\x3e\xb1\x8f\xfd\x2c\x94\xa6\xd3\x32\x51\xda\xcf\xff\xe5\xe6\xea\xeb\xed\xb7\xaf\x50\xaa\x1a\x21\x8e\x59\x63\x1c\x48\x65\x51\x38\x63\x9f\xc1\x94\xe0\x26\xce\x9c\x45\x64\xc9\x79\xf1\xf2\x92\x24\xbb\x1d\x48\x2c\x95\x46\x48\x45\xad\x50\xbb\x14\xe2\xf0\x59\xf3\x50\xc1\xe5\x67\x58\xf1\x16\xe1\x8c\x5d\x19\x5d\xaa\x8a\xfd\xc2\xc5\x03\xaf\x90\x16\xed\x76\xe0\x70\xd3\xd4\xdc\x21\xa4\x6b\xe4\x12\x6d\x0a\x67\xfe\x75\xb5\x69\x8c\x75\x90\x25\x8b\xb4\x36\x55\x9a\x24\x8b\x94\x2c\x1e\x1a\x29\x36\xaa\xb2\xdc\x61\x9a\x2c\x76\x3b\xb0\x5c\x57\x08\x67\xbf\x2d\xe1\x4c\x93\xeb\x33\x76\x6b\x24\xb6\x64\x72\x11\x2c\xe8\x23\x26\xc2\xf8\x38\xe0\x6d\x5d\x00\x6a\xe9\xb1\x2c\xd2\x4a\xb9\x75\xb7\x62\xc2\x6c\x8a\x32\xa6\x45\x69\xd1\xad\xb8\x33\xb6\x40\xed\x0a\xa9\x78\x8d\xc2\x1d\x80\x88\x61\x78\x24\xdf\x9c\xb1\xbc\x42\x76\xe3\xc7\x5a\xb8\x18\x41\xc5\x65\xd1\xb3\x77\x4c\xb3\x79\x92\x14\x05\x5c\x79\x56\x29\xb7\x94\x98\xc0\x31\xb8\x35\x77\xb0\x36\xb5\x6c\x81\xd7\x35\xd0\xd0\xaa\x53\xb5\x44\xdb\xb2\xc4\x3d\x37\xd8\xbf\xd6\x3a\xdb\x09\x07\xbb\x64\x21\x7c\xdc\x21\x34\x55\x12\xa0\xae\x21\xb7\x7f\x0d\x04\x06\x8e\x8a\x02\xbe\x89\x35\x6e\xf8\x9e\xbf\xd2\x58\x10\x16\xb9\x53\xba\x5a\x42\xe0\x5c\xe9\x0a\xb8\x96\x20\xad\x69\x1a\x7a\x68\xfd\x9b\x2c\x59\x2c\xa2\x8d\xf3\x98\x1c\x16\x9e\x67\xb4\x9e\x4a\xd7\x45\x8f\x25\x64\xe6\x96\x6f\x08\xde\x11\x48\x4a\x3b\xb4\x5c\x78\x28\x4f\xca\xad\xfd\xfc\xfc\xa5\x91\x96\xc5\x62\x3e\x73\x3e\x7b\x0c\x7c\x0d\xfc\x47\x84\xa3\x3e\x83\xd7\xa2\x54\x58\xcb\xb6\xe0\x52\x2a\xa7\x8c\xe6\x75\x54\xec\x8b\xcf\xd5\x2d\x3e\x45\xde\x3d\x59\xd8\x02\x07\x8d\x4f\x3d\xe4\x90\x82\xce\xa2\x1c\xd1\x56\xea\x11\x35\x98\x86\xac\xb5\x2c\x29\x3b\x2d\x46\x33\x99\x69\x5c\x0b\x8c\xb1\x3b\x3f\x9f\xc3\x79\x34\x4f\xf9\x24\xc6\x82\xc5\x5d\x6d\xaa\x4b\xa8\x4d\xc5\x7e\xb1\x4a\xbb\x5a\xbf\x24\x0b\xc1\xa2\x4d\x6f\x83\x31\x96\x27\x0b\x8b\xae\xb3\x1a\x7e\x0a\x46\x76\xc9\x22\x8a\xe2\x12\xc4\xd2\xd3\x73\x42\x19\x31\xa7\x97\xd0\xe7\xf4\x16\x9f\xc2\x50\x26\x98\xb4\xea\x11\x6d\xde\x1b\xe9\x09\x7c\x3b\xc7\xf3\x94\x5c\x52\xe4\x47\xb2\x92\x89\x68\x7a\xd8\x1a\x8b\x9e\xf1\xbb\xc6\xb3\x87\x9a\xa8\x16\x46\x6b\x14\x14\x35\x38\xe3\xd9\x95\xdc\x71\x5f\x7f\xda\x06\x85\x2a\x15\x4a\x58\x3d\x87\x19\x0f\x19\x34\xf9\x21\x15\x73\xb2\x16\x06\x2f\xe2\x62\xe1\x5f\xef\x8b\x1e\xad\x5c\xfa\xa5\x81\xc6\xbd\xdc\x72\xe7\xa8\xcc\x4a\xf2\xac\x1c\x0b\xd8\x82\x44\xa0\xe1\x96\x6f\xd0\xa1\x6d\x41\x70\x0d\x2b\x04\x2e\x25\xca\xb0\xab\xa2\x26\x48\xc2\xa3\xba\xa3\x10\x28\xba\x2c\x80\xba\xf5\xee\x09\xd0\x37\x8f\xc7\x13\xd4\x3a\xeb\x37\x64\x4c\xf5\x54\x29\x59\x94\xca\x12\xd0\x5a\x63\x73\x92\x4c\xfb\xa4\x9c\x58\xc3\x68\xd0\xeb\x88\xe8\xd9\xed\xe0\x5f\x46\xe9\x49\x99\xba\x0e\x25\xad\x85\x74\x09\x54\xd2\x2f\x63\x6e\xcf\xdc\xa6\xa9\x29\x91\x0d\x49\xad\x84\x34\xd6\xbe\xe2\x43\x5b\xc4\x3d\x42\xe9\x48\x47\x53\x31\xd5\xf4\xf2\x76\xd8\x4f\xc1\x0c\x0b\x73\x12\x4b\xde\xd5\x8e\x5c\x44\x89\x6a\x55\x2f\xa1\xdc\x38\xf6\x95\xc0\x97\x59\xda\xe9\x36\x88\x12\x65\xc4\x7f\x09\x1f\xbe\xa7\xcb\x49\x30\xf9\xa8\x8a\xfb\xed\x5e\x92\x9c\xe5\xba\xe5\x22\xe6\x63\xc6\x71\x26\xfa\x5d\x95\xc3\xfd\x36\x13\x6e\x4b\x39\x71\xb8\x75\x74\x54\xd0\x7f\x22\xf3\x7e\x3b\x25\x52\x95\xf0\xdb\x12\xcc\x83\xdf\x82\x51\xfd\x2c\x3b\x77\xdb\xeb\xb0\x11\xfe\x44\x73\xbb\x13\xe1\xf4\xc7\x23\x69\x5e\x70\xad\x0d\x55\x6a\x6e\x1d\xf0\x29\x54\x5f\x25\x94\x9e\x0f\xa6\x3e\xce\x85\x0b\x80\x08\x81\xc6\xa7\x00\x7c\x39\x80\xc9\x3d\x46\x9a\xff\xdd\x67\xf2\xfe\x6e\x30\x1e\x85\xaf\xec\x53\x9f\x97\xf0\xe1\x31\xf5\xfe\x82\x73\x51\x56\x93\xea\xd3\xe7\x83\x00\xf8\x4a\x24\x58\x6d\xaa\x25\x48\x5c\x75\xfe\xc9\xff\x78\x19\xeb\xcf\xfd\x76\x56\x7b\xca\x6a\xf9\xbf\xac\x15\x65\x75\x58\x2d\x96\x14\x75\x14\xc7\x35\xa1\xd9\xd3\x87\x47\x78\x11\x75\x01\x37\xee\xf7\x2d\x74\x6d\xd8\xcc\x15\x3a\x78\x44\xbb\x32\x2d\x52\x74\x15\x91\x63\x34\x0c\x35\xc2\x34\x48\x87\xa1\xaf\xde\x45\x91\x14\xc5\x22\x9a\xf1\x7e\xb2\x9c\x46\x3d\x9a\x4c\x69\x89\xdb\x21\xa8\x8f\x79\x0f\x3c\xac\xf8\x5b\x87\xf6\xb9\x5f\x7e\x65\x3a\x0a\xc5\x6d\x73\xb2\x79\xa0\xd3\x68\x7a\x7a\x1c\xa8\xb2\x27\x7a\x9a\x6b\x71\x22\x5d\x71\xe3\x46\x9c\xbd\x72\x96\x21\x7b\xf9\xd1\x54\x3a\xdb\xe1\xcb\xc9\x73\xa4\xcf\xe5\x0f\x9e\x24\x65\xf5\xff\x3f\x4b\x8e\xe9\x23\x4a\xe3\xaa\xa6\x2c\x0b\xfa\xdb\xce\xcf\x8f\xc9\xd1\x42\x47\x40\x63\xf1\x11\xb5\x6b\xbd\x78\xbe\x77\x68\x15\xb6\x50\x5a\xb3\x19\x36\xd0\x91\xea\xe2\xad\x67\x79\xa8\x23\x94\xa5\x3e\x49\x7d\x05\x89\x0b\x92\xd0\x3f\x9f\x8a\x96\x02\x8b\x07\x4f\x5f\x8a\x87\x48\xd3\xab\xb1\x0f\x8f\x3d\x54\x5c\x1a\x7a\x28\x3e\xed\xa0\x0e\x1b\xa6\xbe\x8b\xf3\x5d\xe4\xfc\xe5\x83\x66\x32\x36\xfa\x16\x7d\x33\x72\xa6\xd9\xdf\x51\xa0\x3f\x57\x5f\x5e\x76\x3b\x92\x00\x7e\x0f\xd3\xa9\x48\xc3\x98\x7f\x1a\x4f\x8f\x0f\xec\x53\x9b\x0e\xee\xff\x0d\xb5\x79\xea\xdf\xee\xfb\xef\xd0\x57\xcd\x91\x8c\xbb\xf7\x64\x2c\x3e\x23\x63\x97\x15\x50\x8f\x4d\xd6\xcc\x66\x26\xe2\x7c\x1e\x3a\xc3\xd1\xd9\x98\xa9\x9f\x66\x13\xbb\x41\xf5\x83\x7e\x7c\xd7\x37\x45\x17\x06\x62\x13\xea\x51\xce\x10\x4e\x54\x32\x33\x9d\x47\x53\x59\xbe\xdf\xa6\x06\x83\x7b\x90\xf6\xa6\x47\x60\x2c\xfc\xea\xf1\xfd\xa3\x91\x33\x7c\x1a\xba\x30\xf2\x03\x00\x83\xad\x03\x80\xd1\xc5\x6b\x00\xc3\xf4\x1b\x00\xef\xf4\x5b\x18\xc7\x9c\xa2\x76\xca\x3d\xbf\x05\xf3\x4e\x63\xd6\x8b\xef\xa0\xf5\x3f\x1e\x02\x81\x98\xee\xd1\x61\xf4\xe6\x7a\x62\x8a\xdd\x5c\xe7\xfb\xd8\x6f\xae\xdf\x8d\x5e\xc9\x77\x20\xbf\xb9\xce\x94\x8c\x69\xb9\xb9\x66\xf7\xb4\x31\xdf\x87\xfa\x18\xf7\x77\xfa\x90\xfe\x25\x28\x79\x09\x4a\xbe\x0c\x47\x64\x8d\x33\x1d\xcb\x30\xf0\x03\x32\x09\xa6\x0e\x64\x12\x3d\xbc\x06\x35\x4c\xbf\x2a\x93\x30\x3d\x93\xc9\x31\x88\xef\x57\xc9\x60\xf0\xfd\x2a\x19\x31\x4c\x55\x32\x8c\xbe\xa6\x92\xc9\x82\xf7\x82\x3f\x25\x92\xa9\xbf\x77\x88\xe4\x18\xe8\x63\xcc\x7b\x91\xb0\x3e\x77\xec\x9f\x6b\xb4\x81\x9a\xe9\x3d\x09\xf3\x3e\xf3\xfc\xd5\xea\x47\x07\xe3\xf3\x8f\x88\x26\xf6\x42\x7b\xe0\xfd\xe8\xab\xc0\xfd\xec\xab\x8a\xf9\x19\xdd\x04\xd8\xfc\x94\x08\xe2\xa0\x0f\x43\xe5\xda\x93\x6c\xff\x8c\xee\xd8\x07\x02\x6d\x9f\x23\xd4\x67\x73\xf8\xd3\x0f\x88\x41\x2f\x7d\xd7\x77\x9a\x61\x76\xa7\xeb\xe7\xd0\x0e\x0e\xe1\xfc\x1a\xae\xfb\x1e\x90\x1e\x96\xb0\xea\x1c\x34\x5c\x2b\xd1\xd2\xb1\xcb\x75\xec\x32\x8c\x10\x9d\x6d\x4f\x46\xf4\xeb\x7f\x11\xd2\x3c\x22\x8a\x64\x14\xf9\xf0\x3d\x22\x58\xe4\x89\x8c\x1c\xfd\x12\xf1\x40\xb3\xe1\x73\x22\xb2\x31\x9a\x3a\xec\x80\x30\x36\x18\x5f\x65\x15\xee\xf3\x68\x71\xaf\x2c\x9a\x42\x0f\x32\xf0\x19\xe1\x11\x51\x41\x15\x3b\x68\x78\x2b\x78\x4d\xcb\x7a\xec\x7d\xd7\xd6\x77\x0d\xe3\x0c\xca\x0a\xc1\x94\xfb\x3a\x79\x43\xae\xc7\x9c\xbc\x59\x4d\xfa\x08\x02\x97\x61\xbf\x5c\x7e\x0e\xca\x1e\xe7\x8e\xa8\xda\xf7\xc6\xfe\x12\x09\xb7\x8e\x3a\xa5\x33\x0d\x69\xdf\x7d\xa5\xb1\xe7\x22\xb2\x52\xe2\xae\x6f\xa0\x4f\x7d\xbc\x7b\xe7\x05\x75\x4c\xd3\x6f\xf7\xb7\x3e\xdd\xa7\x2d\x7a\x4c\xa3\x37\x94\xf8\x0c\xf5\x2d\xdc\xf8\x73\x36\x58\x9c\xc3\x97\xf1\x8a\xcd\xdf\x69\xc6\xfb\x11\xf3\x88\xd6\x2a\x89\x12\x94\x06\x63\xfd\x55\xb6\x01\x2e\x25\x8c\x37\x6f\x10\xee\xe2\xfa\xab\x9e\xf8\xd5\xe5\x6f\xa5\x0f\x2e\xa5\x8f\xdd\xdb\x51\x93\x89\x5a\x12\x94\xff\x04\x00\x00\xff\xff\x24\x0b\x75\x10\x89\x17\x00\x00") +var _templateClientTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\xdf\x6f\xdb\x38\xf2\x7f\xb6\xfe\x8a\xf9\x0a\x69\xbf\x52\xe0\x50\x7b\x7d\x3b\x1f\xf2\x50\x24\xbd\xdd\x00\xb7\x49\xef\x9a\xc5\x2d\x50\x14\x5b\x86\x1a\xc9\xbc\xc8\xa4\x4a\x51\x89\x03\x9f\xff\xf7\xc3\x90\xd4\x2f\xdb\x71\xb3\xd9\x7d\x49\x2c\xfe\x98\xf9\x70\xe6\x33\xc3\x19\x69\xb3\xc9\x4e\xa3\x0b\x5d\x3f\x19\x59\x2e\x2d\xbc\xfb\xe1\x2f\x7f\x3d\xab\x0d\x36\xa8\x2c\xfc\x9d\x0b\xbc\xd3\xfa\x1e\xae\x94\x60\xf0\xbe\xaa\xc0\x2d\x6a\x80\xe6\xcd\x03\xe6\x2c\xba\x5d\xca\x06\x1a\xdd\x1a\x81\x20\x74\x8e\x20\x1b\xa8\xa4\x40\xd5\x60\x0e\xad\xca\xd1\x80\x5d\x22\xbc\xaf\xb9\x58\x22\xbc\x63\x3f\x74\xb3\x50\xe8\x56\xe5\x91\x54\x6e\xfe\x1f\x57\x17\x1f\xae\x3f\x7d\x80\x42\x56\x08\x61\xcc\x68\x6d\x21\x97\x06\x85\xd5\xe6\x09\x74\x01\x76\xa4\xcc\x1a\x44\x16\x9d\x66\xdb\x6d\x14\x6d\x36\x90\x63\x21\x15\x42\x2c\x2a\x89\xca\xc6\x10\x86\x4f\xea\xfb\x12\x16\xe7\x70\xc7\x1b\x84\x13\x76\xa1\x55\x21\x4b\xf6\x91\x8b\x7b\x5e\x22\x2d\xda\x6c\xc0\xe2\xaa\xae\xb8\x45\x88\x97\xc8\x73\x34\x31\x9c\xb8\xed\x72\x55\x6b\x63\x21\x89\x66\x71\xa5\xcb\x38\x8a\x66\x31\x49\xdc\x17\x92\xad\x64\x69\xb8\xc5\x38\x9a\x6d\x36\x60\xb8\x2a\x11\x4e\x7e\x9b\xc3\x89\x22\xd5\x27\xec\x5a\xe7\xd8\x90\xc8\x99\x97\xa0\x0e\x88\xf0\xe3\xc3\x80\x93\x75\x06\xa8\x72\x87\x65\x16\x97\xd2\x2e\xdb\x3b\x26\xf4\x2a\x2b\x82\x5b\xa4\x12\xed\x1d\xb7\xda\x64\xa8\x6c\x96\x4b\x5e\xa1\xb0\x7b\x20\xc2\x31\x1c\x92\x4f\x56\x1b\x5e\x22\xbb\x72\x63\x0d\x9c\x0d\xa0\xc2\xb2\xa0\xd9\x29\xa6\xd9\x34\x8a\xb2\x0c\x2e\x9c\x55\xc9\xb7\xe4\x18\x6f\x63\xb0\x4b\x6e\x61\xa9\xab\xbc\x01\x5e\x55\x40\x43\x77\xad\xac\x72\x34\x0d\x8b\xec\x53\x8d\xdd\xb6\xc6\x9a\x56\x58\xd8\x44\x33\xe1\xce\xed\x8f\x26\x0b\x02\xd4\xd6\xa4\xf6\x67\x6f\x40\x6f\xa3\x2c\x83\x4f\x62\x89\x2b\xbe\xa3\xaf\xd0\x06\x84\x41\x6e\xa5\x2a\xe7\xe0\x6d\x2e\x55\x09\x5c\xe5\x90\x1b\x5d\xd7\xf4\xd0\xb8\x9d\x2c\x9a\xcd\x82\x8c\xd3\xe0\x1c\xe6\x9f\x27\x66\x75\xbf\x83\xa9\xf6\x7d\x95\x65\xe0\xbd\x72\xcd\x57\x04\xed\x00\x1c\xa9\x2c\x1a\x2e\x1c\x8c\x47\x69\x97\x6e\x7e\xba\x69\x30\xc9\x6c\x36\x9d\x39\x9d\x3c\x7a\x5b\xed\xc2\x1b\x91\xd3\xab\xcd\x0a\x89\x55\xde\x64\x3c\xcf\xa5\x95\x5a\xf1\x2a\xd0\x75\xeb\x1c\x75\x8d\x8f\xc1\xe8\xce\x52\xd8\x00\x07\x85\x8f\x1d\x66\x6f\xff\xd6\x60\x3e\xc0\x2d\xe5\x03\x2a\xd0\x35\x49\x6b\x58\x54\xb4\x4a\x0c\x62\x12\x5d\xdb\x06\x18\x63\x37\x6e\x3e\x85\xd3\x20\x9e\x9c\x59\xb8\xd0\xf2\x32\x37\x95\x2e\x17\x50\xe9\x92\x7d\x34\x52\xd9\x4a\xcd\x61\xa9\xf5\x7d\xb3\x80\xb7\xee\xff\x86\xce\x23\x8a\x92\x05\x45\x4e\x30\x63\x2c\x8d\x66\x01\xdb\xe2\x1c\xde\x7a\xe1\x1b\x2f\x72\x01\xa2\x28\xb7\xdd\x3c\x93\x4a\xda\x24\x8d\x66\x06\x6d\x6b\x54\x38\x11\x1d\xdb\x21\x4e\x44\x07\x2d\x05\xbf\x92\x20\x1e\xe5\x99\x08\x94\x80\x73\xe8\x38\x72\x8d\x8f\x7e\x2c\x11\x2c\x37\xf2\x01\x4d\xfa\x62\xc2\x00\x00\xcc\x04\x9b\xfa\xf8\x1c\xc8\x96\x07\x1c\x9d\x08\xe6\x4f\x39\x55\xe0\xbd\x78\x53\x3b\x8f\xa0\x22\xf7\x09\xad\x14\x0a\x32\x1a\x58\xed\x3c\x96\x73\xcb\x5d\x42\x6b\x6a\x14\xb2\x90\x98\xc3\xdd\x93\x9f\x71\x98\x41\x91\x26\x0a\x0b\x4e\xd2\xfc\xe0\x59\x58\x2c\xdc\xf6\x2e\x8b\xd2\xca\xb9\x5b\xea\xcd\xba\xc3\x17\x6e\x2d\xe5\xed\x9c\x34\x4b\xcb\x3c\x36\x4f\x3b\xa8\xb9\xe1\x2b\xb4\x68\x1a\x10\x5c\xc1\x1d\x02\xcf\x73\xcc\x7d\x98\x06\x9e\x51\x5c\x0c\x21\x13\xc8\x45\xa7\x4b\x3c\xa8\x6b\xa7\x9e\x00\x7d\x72\x78\x9c\x89\x1a\x6b\x5c\x84\x07\xa6\x8c\xd9\x97\x04\x1f\xcf\x01\x8d\xd1\xc6\xf9\xb8\x79\x94\x56\x2c\x61\x10\xe8\xb8\x49\xe6\xd9\x6c\xe0\x3f\x5a\xaa\x51\xde\xbb\xf4\x39\xb2\x81\x78\x0e\x74\x47\x2c\x5c\x50\x9e\xc1\x89\x5d\xd5\x15\xf9\xb3\x26\xf2\x16\x10\x87\x64\x9a\xbd\x69\xb2\x10\x77\xe4\x8e\x78\x10\x15\x52\x27\x6d\x5e\xf7\x31\xea\xc5\x30\x3f\x97\x63\xc1\xdb\xca\x92\x8a\x40\x59\x25\xab\x39\x14\x2b\xcb\x3e\x10\xf8\x22\x89\x5b\xd5\x78\x5e\x62\x1e\xf0\x2f\xe0\xcd\xb7\x78\x3e\x3a\x4c\x1a\xcd\x3a\x56\xdc\xae\x77\x9c\x64\x0d\x57\x0d\x17\xc1\x1f\x13\x1b\x8f\xc3\xe1\x76\x9d\x08\xbb\x26\x9f\x58\x5c\x5b\xba\x7b\xe8\x3f\x19\xf3\x76\x3d\x36\xa4\x2c\xe0\xb7\x39\xe8\x7b\x17\xd4\x81\xfe\x2c\x39\xb5\xeb\x4b\x1f\x09\x7f\xa3\xb9\xcd\x91\xe3\x74\xf7\xed\x76\xbb\x20\x4a\x28\x4d\xa9\x9f\x1b\x0b\x7c\x0c\xd5\x65\x1e\xa9\xa6\x83\xb1\x3b\xe7\xcc\x7a\x40\x84\x40\xe1\xa3\x07\x3e\x87\x51\x2c\xca\xc2\xcd\xff\xdf\x39\x69\x7f\x31\x18\x87\xc2\x5d\x15\x63\x9d\x0b\x78\xf3\x10\x3b\x7d\x5e\xf9\x34\x9f\x75\xfe\x20\x00\x2e\xb7\x09\x56\xe9\x72\x0e\x39\xde\xb5\xee\xc9\xfd\xe8\xb3\x9c\x60\xee\xc7\xb6\xcf\x4f\x6f\x6f\xd7\x04\x6f\x94\xca\xe6\xfe\x06\x78\xae\x3e\xf0\x84\x9a\xde\x11\x8b\x67\xb3\x47\x51\xa6\x41\x5e\x77\x53\xcf\xb6\x73\xb2\x42\x20\xcb\x25\xa1\xdb\xe1\x8b\x43\x7c\x16\x78\x02\x57\xf6\xff\x1b\x68\x1b\x1f\xdc\x25\x5a\x78\x40\x73\xa7\x1b\xa4\xd3\x96\x64\x2c\xad\xa0\xcf\x19\xba\x46\xba\x6d\xdd\x0d\x91\x65\x51\x96\x75\x59\xd9\xe9\x49\x52\x1a\x75\x68\x12\xa9\x72\x5c\xf7\x87\xfa\x21\xed\x80\xfb\x15\xff\x6c\xd1\x3c\x75\xcb\x2f\x74\x4b\x47\xb1\xeb\x94\x64\xee\xf1\x36\x88\x1e\x5f\x39\xb2\xe8\x0c\x3f\xf6\xbd\x38\xe2\xbe\x10\xc8\x01\x67\xc7\xa4\xb9\xf7\x66\x7a\xd0\xb5\xd6\xb4\x78\xc0\xaf\x7f\xf4\x9a\x72\x65\x14\xd9\x57\xd0\xdf\x66\x9a\xc9\x47\x49\x9e\x92\x71\x6d\xf0\x01\x95\x6d\x9c\xdb\xbe\xb5\x68\x24\x36\x50\x18\xbd\xea\xa9\x7c\x20\xce\x9d\xf4\x24\xf5\x11\x4d\xf6\xe9\x20\x74\xb1\x1c\x16\x04\x30\xbf\x34\x2e\x63\x7b\x20\xab\xd6\x3a\xf7\xfa\x63\x13\x23\xa8\xa4\xa3\x19\x54\x56\xda\xa7\x70\x0e\xe7\x7d\xb8\x52\xa0\x8d\xab\xec\x35\x49\x18\xed\x19\x08\x23\x42\x9e\x16\xbc\xaa\x16\xf0\x35\x18\x87\x48\xc1\x7e\x69\x30\xa1\x9b\xff\xeb\x81\x33\xd0\x9c\x17\xc7\x18\xfb\x49\xeb\xfb\xfe\x1a\x3f\x5a\x56\xef\x5c\xbb\xac\x17\xe3\x2b\x8c\xe9\x05\x1b\x1d\x2f\xd2\x49\xd2\xe0\x6b\x77\x21\xf4\xa2\xe3\x8b\xa1\xbd\x08\xe5\x61\x58\xea\xcb\x43\x3e\x2e\x0e\xf7\x6b\xc1\xae\x38\x75\xc5\xf1\x74\xf3\x5e\x8d\x1c\xfa\x17\x83\xc2\xe1\x53\xec\x5f\x28\xd0\xdd\xee\xdb\xed\x66\x43\x55\x0d\x7e\xf3\xd3\xb1\x88\xfd\x98\x7b\x1a\xee\xb0\x37\xec\x5d\x13\xf7\xea\xff\x0b\x95\x7e\xec\x76\x77\x6d\x85\xaf\x18\xa7\x48\x86\x9c\x71\xf4\x2c\x8e\x8d\x43\xfd\xe8\x51\x0f\xe5\xe3\x44\x66\x22\xc2\x7c\xea\x8b\xde\x41\xd9\xc0\xd2\xb7\x93\x89\x21\xb6\xb6\xbb\x74\xe5\x50\xc9\xc6\x52\x3b\xb8\x4f\x5a\xc2\xe3\x1f\x1a\xcb\xc5\xbd\x63\xeb\x7b\xc7\x41\x9a\xfd\x4a\xb4\x28\xe6\x40\x59\x3b\xfd\x0a\xf8\xad\xe5\x95\xdb\xf6\x75\xb7\xfb\x72\xd4\x6b\x92\x22\x29\x93\x65\x92\xa6\xe9\x84\xab\x13\xa0\xcf\x51\x36\xe4\x8d\xbd\x72\x90\xd7\x35\xaa\x3c\x39\x38\x1d\x92\x8e\xe3\x6c\x48\x18\xae\x88\x1f\xbb\xc4\x0f\x84\xa6\xc2\xb9\x66\xca\xfc\x67\x61\x7a\x51\x49\xba\xdb\x76\x78\x81\x9b\x68\xd6\x5b\xd3\x5f\xbe\x7e\xd5\xcf\x61\x30\xac\xee\xab\xd6\x39\xdc\xd4\x7e\x6b\x3a\xf5\xe0\x8e\xe0\xc1\x8f\xfd\xc6\x3e\xb1\x7a\x1b\xa7\xf3\xde\x8f\x8b\xfe\x57\xef\xf4\x3a\x9f\x9c\x5f\x41\xeb\x47\x5e\x61\x00\x2f\x6b\xcf\x00\x41\xc5\x6b\x0c\xe0\xb7\x3e\x67\x00\x3f\xfb\xa7\x18\xe0\x46\x7d\xcf\x06\x43\x20\xfa\x7c\xfd\x3d\x33\xdc\x28\x4c\xba\x8c\xb1\xd7\x8a\x1e\x36\x11\x81\x18\x5f\x2a\xfd\xe8\xd5\xe5\x48\x14\xbb\xba\x4c\x77\xb1\x5f\x5d\xbe\x18\xbd\xcc\x5f\x80\xfc\xea\x32\x91\x79\x70\xfb\xd5\x25\xbb\xa5\x6c\xfa\x1d\xd4\xaf\xf4\xed\x8d\x22\xf7\x76\x9b\x99\xcc\xe1\x1c\xde\xca\xfc\xa8\xc7\x6f\xd4\x1f\x75\xfa\x25\x56\x38\x89\xfa\xdc\x0f\xbc\x82\xf4\x5e\xd4\x1e\xe9\x83\x86\xd7\x18\xc6\x6f\x7d\x8e\xf4\x7e\xf6\x4f\x39\xff\x84\xf4\x87\x4c\xf0\x72\xce\xf7\x02\x5f\xce\xf9\x01\xc3\x98\xf3\xfd\xe8\x73\x9c\x1f\x2d\x78\x29\xf8\x63\x94\x1f\xeb\x7b\x01\xe5\x27\xa0\x3b\x6d\xae\x9b\xeb\x78\xc0\xfe\xbd\x44\xe3\xcd\x30\xb9\xef\x9c\xfc\x34\xed\x77\xb1\x03\x9c\xdf\x9b\xd2\x35\x9c\xf7\x8c\xb8\x51\x78\x94\x13\x14\x16\x41\xc2\xf6\xb9\xdb\x8d\x2a\xdd\xa7\xd7\xd0\x3c\xb4\x15\x3b\xe6\x70\xa3\xbb\x25\xc6\x74\x76\x8f\xa9\x1d\xb6\x1f\xd1\x8e\x80\x4d\x6f\xf1\x50\x12\xdf\x3d\x81\xb4\xcd\x51\xff\xfd\x88\xf6\x50\xef\x3d\x87\x83\xce\x4c\x4e\x77\xca\x81\xa1\x37\xef\x19\xd8\x35\x50\xc7\xfd\xc8\x6e\x54\xf5\xe4\x3b\xab\xfe\x38\xbf\xfa\x57\xf3\xf7\x48\x0f\x73\xb8\x6b\x2d\xd4\x5c\x49\xd1\x50\x2d\xc9\x55\x68\x1b\xb4\x10\xad\x69\x8e\x9e\xe8\xd7\xdf\x71\xa4\xe9\x89\x7c\x2d\xdf\x85\x4d\xdf\xea\x0b\x16\xec\x44\x42\x0e\x36\xf9\x0e\x68\xd2\x77\xea\xc1\x1a\x83\xa8\x50\x2d\x8f\xaa\x7a\x0c\x55\xf3\x87\xbc\x1c\xca\xfa\x51\x48\x9c\xa0\x03\xe9\xed\x19\xe0\x91\xa1\x3c\x2b\x36\x50\xf3\x46\xf0\x8a\x96\x75\xd8\xbb\x36\xac\x2b\x85\x87\x19\xcc\x4b\xa4\x7a\x94\xff\x2e\xba\x1e\x52\xf2\xdd\xfc\xd4\x9d\xc0\xdb\xd2\xc7\x0b\x75\xa4\xd3\xb9\x03\xac\x76\x3d\x90\x7b\xe7\x8b\x6b\x4b\xe5\xff\x89\x82\xb8\x6b\x29\xe2\xd0\x48\x90\xb1\x62\xb2\x5d\x78\xb7\x75\xf4\xbd\x98\x53\x9e\x51\x1b\x30\x7e\x2d\xf6\xbd\xb7\x62\xe3\x97\xa9\xc1\x8d\x4e\x50\xe4\x3c\x34\xea\x4b\xdc\x3d\xd1\x87\xe0\xe8\xbd\xbb\xaf\x91\x9f\xb5\x6d\xb8\x5f\xe0\xf3\x17\xfa\x35\x7a\x09\xac\x8d\x33\x67\xbb\xf2\x92\x4f\x14\xfb\x89\x37\x1f\x75\x25\xc5\x93\x47\xed\x8b\x78\xc7\xc7\x03\xc5\xf9\xf0\xba\x21\x94\xf0\x6e\xcd\xe7\x45\x85\xca\xff\x4c\x47\x3f\xbf\xcc\xe1\x70\x4b\xf1\x79\xf1\x65\xd4\x92\x56\xcd\x54\xf2\x33\x8a\xa7\xed\xeb\x60\xa6\x91\xc1\x36\x9b\xec\x14\xde\x0f\x5f\x0b\xdc\xb7\x99\xf0\x5a\x56\x3f\xa0\x31\x32\xc7\x1c\xe4\x4e\xe3\x3e\x7c\x44\x00\xff\x59\xa1\xeb\xa1\x42\xbb\xee\xbe\xae\xed\x7d\x5c\x3b\xf4\x09\x82\xba\x4a\x54\x39\x41\xf9\x5f\x00\x00\x00\xff\xff\x03\x1a\x89\x10\x51\x1c\x00\x00") func templateClientTmplBytes() ([]byte, error) { return bindataRead( @@ -255,12 +279,12 @@ func templateClientTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/client.tmpl", size: 6025, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/client.tmpl", size: 7249, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateConfigTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x53\x4f\x6b\xdc\x3e\x10\x3d\xaf\x3e\xc5\x63\xc9\x61\x37\xe4\xa7\xcd\x2f\xb7\x16\xf6\x10\x92\x14\x02\xa1\x2d\xb4\xf7\x22\x4b\x63\xaf\x1a\x47\xe3\x4a\x72\x68\x30\xfb\xdd\x8b\xfe\x38\xeb\x40\x0e\xb9\x79\xf4\xde\xbc\x99\x79\x33\x9e\xa6\xdd\xb9\xb8\xe1\xe1\xc5\xdb\xee\x10\x71\x75\xf9\xff\xa7\xff\x06\x4f\x81\x5c\xc4\x17\xa5\xa9\x61\x7e\xc4\xbd\xd3\x12\xd7\x7d\x8f\x4c\x0a\x48\xb8\x7f\x26\x23\xc5\xcf\x83\x0d\x08\x3c\x7a\x4d\xd0\x6c\x08\x36\xa0\xb7\x9a\x5c\x20\x83\xd1\x19\xf2\x88\x07\xc2\xf5\xa0\xf4\x81\x70\x25\x2f\x67\x14\x2d\x8f\xce\x08\xeb\x32\xfe\x70\x7f\x73\xf7\xf5\xc7\x1d\x5a\xdb\x13\xea\x9b\x67\x8e\x30\xd6\x93\x8e\xec\x5f\xc0\x2d\xe2\xa2\x58\xf4\x44\x52\x9c\xef\x8e\x47\x21\xa6\x09\x86\x5a\xeb\x08\x6b\xcd\xae\xb5\xdd\x1a\xf5\xf9\x6c\x78\xec\xf0\x79\x8f\x46\x05\xc2\x99\xbc\xc9\xa8\xfc\xae\xf4\xa3\xea\x28\x91\xa6\x09\x91\x9e\x86\x5e\x45\xc2\xfa\x40\xca\x90\x5f\xe3\x6c\x4e\x3f\x41\xf6\x69\x60\x1f\x67\x68\xb7\xc3\xb7\x21\x5a\x76\x68\x47\xa7\xf3\x47\x64\x94\xda\xa3\xa7\xdc\xbe\xee\x2d\xb9\x28\x45\x7c\x19\x68\xc9\xde\x9c\x17\xde\x36\xcb\x94\x8e\x92\x6b\x39\xa7\x2a\xa8\xc2\x66\xbf\x50\x82\x72\x06\x36\x06\x34\xa3\xed\x0d\xf9\xaa\x5c\x52\x10\xa2\x1f\x75\xc4\x24\x56\xbb\x1d\x8c\xb7\xcf\xe4\x31\xa6\x1d\x24\x11\xfa\x4b\x7a\x8c\xd6\x75\x30\x2a\xaa\xec\x85\xa7\x3f\x23\x85\x18\xa4\x58\x55\xb6\xb1\xaa\x27\x1d\xe5\x6d\x0e\x8b\x0e\x35\x63\x07\x72\xaa\xe9\x09\xaa\x86\x3d\x77\x9d\x75\x5d\x4a\xcc\x71\xc3\xdc\x67\x76\xcf\xdd\xa9\x64\x65\x81\x5d\x4d\x7b\x62\x43\x52\xac\x12\x29\xbb\x20\xa5\xb4\x2e\x92\x6f\x95\xa6\xe9\xb8\x15\x4b\x57\x03\xd4\x30\xf4\x96\x8a\x29\x5c\xdf\xd8\x2d\x3c\x02\x37\xbf\x53\xb7\x22\x89\x61\xa3\x31\xbb\x3a\xd3\x37\x3c\xc4\x00\x29\x65\x91\xdc\x26\x6b\x52\x63\xbf\x2e\x12\x23\xdd\x84\x57\xae\xcb\xea\x21\x61\x2b\x1e\xe2\x46\x6f\xc5\xea\x28\x56\xb6\x85\x96\xa5\xed\x84\x68\x59\x2d\xda\x9f\x4c\x4a\xe0\x66\x06\x2e\xa0\x65\xcf\x5d\x4e\x2e\x73\xdc\x2e\x9c\x0b\x6f\x8d\x9b\xe7\x48\xc7\x51\xbc\xae\x43\x14\xcd\xed\x7c\x2b\x93\x58\x79\x8a\xa3\xaf\x57\xb3\x98\xb0\xf6\x94\x45\xf7\x88\x7e\xa4\x53\xe1\x07\xee\x10\x28\x16\xe7\xe6\x8a\xaf\x47\x9a\x0c\x58\xae\x23\xd7\x7d\xe0\x6e\xd3\xba\x77\xb7\xf2\xe1\x66\xd2\x5a\xf7\x68\xdd\xc2\x81\x62\xd9\xeb\x3f\x11\x96\xa7\x6c\xde\xcc\x9d\x83\xcd\xbb\x67\xf8\x71\x37\x5e\x37\x54\xcf\x37\xf7\x31\x4d\x20\x67\x70\x3c\xfe\x0b\x00\x00\xff\xff\x05\x81\xda\x42\xe6\x04\x00\x00") +var _templateConfigTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x53\x4d\x6f\xe3\x36\x14\x3c\x8b\xbf\x62\x60\xf8\x60\x1b\x59\x7a\xbb\xb7\x16\xf0\x61\x91\xdd\xa2\x01\x82\xb4\x40\x7b\x2b\x8a\x82\x26\x9f\x64\xd6\x32\x9f\x4a\x52\x41\x03\xc1\xff\xbd\xe0\x87\x62\x05\xc8\x21\x27\x89\x7c\xf3\xbe\x66\x86\xd3\xb4\xdf\x89\x7b\x1e\x5e\xbc\xed\x4e\x11\x5f\x3e\xff\xf0\xe3\xa7\xc1\x53\x20\x17\xf1\xb3\xd2\x74\x64\x3e\xe3\xc1\x69\x89\xaf\x7d\x8f\x0c\x0a\x48\x71\xff\x4c\x46\x8a\x3f\x4e\x36\x20\xf0\xe8\x35\x41\xb3\x21\xd8\x80\xde\x6a\x72\x81\x0c\x46\x67\xc8\x23\x9e\x08\x5f\x07\xa5\x4f\x84\x2f\xf2\xf3\x1c\x45\xcb\xa3\x33\xc2\xba\x1c\x7f\x7c\xb8\xff\xfe\xf4\xfb\x77\xb4\xb6\x27\xd4\x3b\xcf\x1c\x61\xac\x27\x1d\xd9\xbf\x80\x5b\xc4\x45\xb3\xe8\x89\xa4\xd8\xed\xaf\x57\x21\xa6\x09\x86\x5a\xeb\x08\x2b\xcd\xae\xb5\xdd\x0a\xf5\x7a\x3d\x9c\x3b\xfc\x74\xc0\x51\x05\xc2\x5a\xde\xe7\xa8\xfc\x4d\xe9\xb3\xea\x28\x81\xa6\x09\x91\x2e\x43\xaf\x22\x61\x75\x22\x65\xc8\xaf\xb0\x9e\xd3\x6f\x21\x7b\x19\xd8\xc7\x39\xb4\xdf\xe3\xd7\x21\x5a\x76\x68\x47\xa7\xf3\x4f\x64\x94\xde\xa3\xa7\x3c\xbe\xee\x2d\xb9\x28\x45\x7c\x19\x68\x89\xde\xec\x0a\x6e\x9b\xcb\x94\x89\x12\x6b\x39\xa7\x56\x50\x05\xcd\x7e\x51\x09\xca\x19\xd8\x18\x70\x1c\x6d\x6f\xc8\xd7\xca\x25\x05\x21\xfa\x51\x47\x4c\xa2\xd9\xef\x61\xbc\x7d\x26\x8f\x31\x69\x90\x8a\xd0\x7f\xa4\xc7\x68\x5d\x07\xa3\xa2\xca\x5c\x78\xfa\x77\xa4\x10\x83\x14\x4d\x45\x1b\xab\x7a\xd2\x51\x7e\xcb\xc7\x52\x87\x8e\x63\x07\x72\xea\xd8\x13\x54\x3d\xf6\xdc\x75\xd6\x75\x29\x31\x9f\x8f\xcc\x7d\x46\xf7\xdc\xdd\x5a\x56\x14\xd8\xd5\xb4\x0b\x1b\x92\xa2\x49\xa0\xcc\x82\x94\xd2\xba\x48\xbe\x55\x9a\xa6\xeb\x36\x57\x38\x31\x9f\x43\x62\xb2\x0c\x4c\x29\xfb\x32\xc6\xcc\x46\x9a\xb4\xc4\x77\xf9\x23\x8a\x0c\xe5\x6a\x20\x5f\x59\xba\xcb\xdd\x5b\x15\x22\x94\xd6\x14\x42\xa5\xa9\xe0\x6e\x2c\x4d\xd3\x27\x78\xe5\x3a\xc2\xda\x25\x83\xac\xe5\x13\x1b\x0a\x49\x5d\x00\x68\x92\x77\x9c\x7c\x52\x97\xe4\x12\xfc\xf9\x57\x92\xf2\x17\xe6\x73\xc9\x24\x67\x12\x72\xe9\x84\x00\x35\x0c\xbd\xa5\x22\x24\xd7\x3b\x76\x0b\x5d\xc1\xc7\x7f\x12\xc3\x22\x11\x80\x8d\xc6\xec\x84\x19\xbe\xe1\x21\x06\x48\x29\x4b\xc9\x6d\x1a\x34\xad\xf3\xf7\x5d\x42\xa4\x31\xcb\xc8\x19\x36\x89\xa6\xe1\x21\x6e\xf4\x56\x34\x57\xd1\xd8\x16\x5a\x16\xaa\x53\x44\xcb\x2a\xeb\xe1\x26\x6c\x0a\x6e\xe6\xc0\x1d\xb4\xec\xb9\xcb\xc9\x65\x8f\x6f\x0b\xb5\xc3\x5b\xb1\xe7\x3d\x12\x0b\xc5\x1f\x75\x89\x52\x73\x3b\xfb\x7b\x12\x8d\xa7\x38\xfa\xea\xf4\xc5\x86\x75\xa6\x5c\xf4\x80\xe8\x47\xba\x35\x7e\xe4\x0e\x81\x62\x61\x6e\xee\xf8\xfa\xb0\x12\x01\x4b\x0b\xe5\xbe\x8f\xdc\x6d\x5a\xf7\xae\x93\x3e\x3c\x4c\xb2\xe2\x01\xad\x5b\x30\x50\x28\x7b\x7d\xc7\x61\xf9\xfc\xcc\x9b\xbd\xf3\x61\xf3\xee\xd3\xf9\x38\x1b\xaf\x0a\xd5\x27\x97\xe7\x98\xa6\x6a\xaf\xff\x03\x00\x00\xff\xff\xf5\xf2\xe9\x13\x9a\x05\x00\x00") func templateConfigTmplBytes() ([]byte, error) { return bindataRead( @@ -275,7 +299,7 @@ func templateConfigTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/config.tmpl", size: 1254, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/config.tmpl", size: 1434, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -320,7 +344,7 @@ func templateDialectGremlinByTmpl() (*asset, error) { return a, nil } -var _templateDialectGremlinCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x56\x5d\x8f\xda\x38\x17\xbe\x4e\x7e\xc5\x79\x11\xad\x12\x94\x1a\xda\xbb\x77\x56\x5c\xcc\xb2\x54\x45\xea\x4e\x3f\x66\x76\x6e\xaa\x6a\xe4\xb1\x4f\xc0\x9a\x60\xa7\xb6\x43\x8b\x50\xfe\xfb\xea\x38\x01\x42\x60\x56\xfb\x79\x45\xe2\xf3\xf5\x9c\xe7\x3c\x27\x66\xb7\x1b\x8f\xe2\x99\x29\xb7\x56\x2d\x57\x1e\xde\x4c\x5e\xff\xff\x55\x69\xd1\xa1\xf6\xf0\x96\x0b\x7c\x34\xe6\x09\x16\x5a\x30\xb8\x2e\x0a\x08\x4e\x0e\xc8\x6e\x37\x28\x59\x7c\xb7\x52\x0e\x9c\xa9\xac\x40\x10\x46\x22\x28\x07\x85\x12\xa8\x1d\x4a\xa8\xb4\x44\x0b\x7e\x85\x70\x5d\x72\xb1\x42\x78\xc3\x26\x7b\x2b\xe4\xa6\xd2\x32\x56\x3a\xd8\xdf\x2f\x66\xf3\x9b\xdb\x39\xe4\xaa\x40\x68\xcf\xac\x31\x1e\xa4\xb2\x28\xbc\xb1\x5b\x30\x39\xf8\x4e\x31\x6f\x11\x59\x3c\x1a\xd7\x75\x1c\xef\x76\x20\x31\x57\x1a\x61\x20\x15\x2f\x50\xf8\xf1\xd2\xe2\xba\x50\x7a\x2c\x2c\x72\x8f\x03\xa8\x6b\xf2\x1a\x3e\x56\xaa\x20\x4c\x57\x53\x28\xb9\x13\xbc\x80\x21\xbb\x15\xa6\x44\xf6\x73\x6b\x69\x1d\x2d\x0a\x54\x9b\xc6\xf3\xf0\x7c\x08\xa7\xa2\x79\xa5\x05\x24\x27\xbe\x75\x0d\xa3\x6e\x95\xba\x4e\xa1\x05\x72\xcb\x37\x98\x08\xff\x03\x84\xd1\x1e\x7f\x78\x36\x6b\x7e\x53\x48\x42\x08\xbb\xe1\x6b\x84\xba\xce\x00\xad\x35\x36\x85\x5d\x0c\x00\x44\x34\x21\x78\xd9\x66\x61\x9f\xd1\x95\x46\x3b\xdc\xd5\xc1\xfc\xad\x42\xbb\xcd\xe0\x51\x69\xa9\xf4\x32\xb8\xf6\x00\xb1\x36\x32\x49\xd9\x27\x72\x4e\xd2\x38\x52\x39\x15\xb9\xe4\x2c\x2d\x3d\xb1\xf9\x0f\x14\x04\x36\xeb\x17\xc8\x08\x50\xfa\x53\x08\xff\xdf\x14\xb4\x2a\x60\x17\x47\x91\x45\x5f\x59\x4d\xaf\x01\x7e\x1c\xd5\xfb\x22\x19\x98\x27\x2a\xa4\xdc\xcc\x68\xe7\xb9\xf6\x73\x6a\x2f\x69\xd2\x98\xa7\x67\xc3\x03\x27\x9f\x3b\xc4\x12\x0b\x5d\xa2\x76\xc2\xe8\x5c\x2d\xaf\xce\x7a\x68\xce\xeb\x7e\x9b\xdd\x64\xec\xad\x35\xeb\x3d\x95\xc9\x9f\x6e\xa9\x3d\xeb\x67\xcb\xc8\x2b\xfe\xcb\x8a\x48\x52\x18\x49\x57\xb0\x3b\xcb\x37\x68\x1d\x0f\x75\x77\xbb\x57\xf0\x5d\xf9\x15\xb0\x9b\x6a\x1d\x28\xb3\x5c\x69\x4f\x82\x8b\x22\xbf\x2d\x69\xc9\x0e\x87\xce\xdb\x4a\xf8\x00\x37\x2a\x2d\xca\x7e\xbe\xf1\xb8\xeb\x4d\x1e\x4a\x70\x8f\x8c\xfc\x3d\x3a\x7f\xc1\x3f\x1c\xaf\xb9\x17\x2b\x74\xc0\xb5\x04\xe5\x5d\x93\x84\x6b\x4f\x81\x84\xe3\x98\x34\x28\x6e\xcd\x9f\x30\xf9\xf2\x75\x74\x3c\xce\x60\x92\x11\x4d\x8c\xfa\x6d\x9a\x42\x2d\x43\x13\x1b\x8a\x58\xb2\x6b\x29\xef\x03\x53\xec\x23\x17\x4f\x7c\x49\x13\x65\xef\xf9\x23\x16\xad\xbf\xe5\x7a\x89\x30\x7c\xc8\x60\x98\x53\xc8\x90\xbd\x55\x58\x48\xd7\x30\xa1\xf2\xb3\xb1\x53\xd0\x30\xdf\xaf\x71\x70\x26\xf6\x3b\x23\x0d\x79\x55\x4e\x5e\xbf\x69\xf5\xad\xc2\x26\xd7\x69\x3f\x53\xe0\x65\x89\x5a\x26\x9d\xc3\x0c\x5e\x1e\xdf\x42\xa6\x86\xef\x2b\x58\xb2\xfb\x24\x65\xef\xb8\xbb\xdc\x4b\x06\xfd\x63\x7a\xcf\xd9\x7e\x17\x82\x78\x46\xe7\x9d\x5c\x68\x24\x65\x33\x53\x69\x9f\xa4\x59\x53\x9f\x06\x75\x05\x0f\x0f\x6c\xe1\x92\x92\xdd\xcc\x3f\x25\x93\x34\x3d\x24\x4e\x6e\xf0\xfb\xdc\xda\xa6\xcd\x90\xe2\xbf\x07\xd8\x22\xa3\x81\x47\x27\x23\x8f\xa2\x0d\xfb\x68\x4d\x89\xd6\x6f\x13\x52\xdc\xad\xd2\xcb\x02\xff\xcd\xda\x8d\x30\xbb\x45\x7b\x1a\xc2\x46\x43\x73\xb9\xc4\x56\x42\x41\x2f\xcd\xed\xa2\x8c\x26\xf3\x60\xa1\x07\x1d\x9b\xa6\xef\x0c\xdd\x13\x56\x69\x9f\xc3\xe0\x85\x63\x2f\xdc\xa0\x83\x78\x88\x5d\xac\x71\x14\xe5\xc6\x82\x92\xe1\xc6\x08\x95\x2f\x61\xc7\x33\x85\x9e\x48\x13\xd9\xc2\x2d\x34\xed\xe3\x41\x9d\x3d\xa0\x53\x18\x7c\xa8\xfc\xe0\xc4\x1a\xa0\x9e\x23\x45\x76\xb7\x2d\xf1\x79\xbc\x34\x98\x6b\x29\xe7\x41\x1b\xba\xf9\xac\xa6\xe1\xdb\x98\x90\xb0\x95\x4c\x53\xb6\xd0\xf7\xc9\x71\xa2\xc5\x11\xd6\xa5\xd0\x3b\x73\x0c\xfc\x50\xf9\x6e\xe4\x41\x0b\xc7\x4e\xdf\x71\xd7\xff\xc2\xfd\xb3\x5d\x9c\x37\xbb\x18\x94\x7d\x0a\x8c\x5e\x8e\x14\xd6\x75\xbb\xb5\x8b\x5f\x08\xeb\xdf\xdf\x2c\x92\xd3\x1f\x2d\x96\xde\xdf\xe9\xc4\xc8\xb3\xeb\x71\x41\xb9\xcf\x5e\x01\x2a\x87\x02\x75\x97\x90\x14\xa6\x53\x98\x34\x2a\x6a\x2f\xa8\x0d\xbb\xe7\x45\x85\xbf\xf2\x32\xf1\xb6\xc2\x76\x3b\x22\x1f\xee\xc2\x4e\xe8\x97\xc9\x57\x46\xdc\xb1\x99\xe1\x05\x3a\x81\x49\xcf\x48\x54\x64\x67\xe9\xd2\x56\xea\x0f\x19\x08\x7b\x54\x7b\x37\xf6\xf5\xd5\xd7\x06\x91\xb7\x30\x05\x61\xfb\x65\x6c\x9b\xda\xdb\x3d\xb8\x16\xba\xb7\x71\x4f\x69\xcf\xf6\xd4\xe1\x2c\xfc\x65\x6b\x9f\x7f\x0f\x00\x00\xff\xff\xb2\x46\x21\x32\xd0\x0a\x00\x00") +var _templateDialectGremlinCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\x4d\x6f\xdb\x38\x13\x3e\x4b\xbf\x62\x5e\xc3\x2d\xa4\x40\xa5\xdd\xde\xde\x2c\x7c\xc8\xba\xee\xd6\x40\x9b\x7e\x24\x9b\x4b\x11\x04\x0c\x39\xb2\x89\xc8\xa4\x4a\x52\x6e\x0c\x43\xff\x7d\x31\x94\x6c\xcb\x8a\xb3\xbb\xdd\x9e\x62\x71\xbe\x9e\x79\xe6\x19\x32\xdb\xed\xe8\x2c\x9e\x9a\x72\x63\xd5\x62\xe9\xe1\xcd\xf8\xf5\xff\x5f\x95\x16\x1d\x6a\x0f\xef\xb8\xc0\x7b\x63\x1e\x60\xae\x05\x83\x8b\xa2\x80\xe0\xe4\x80\xec\x76\x8d\x92\xc5\xd7\x4b\xe5\xc0\x99\xca\x0a\x04\x61\x24\x82\x72\x50\x28\x81\xda\xa1\x84\x4a\x4b\xb4\xe0\x97\x08\x17\x25\x17\x4b\x84\x37\x6c\xbc\xb3\x42\x6e\x2a\x2d\x63\xa5\x83\xfd\xc3\x7c\x3a\xbb\xbc\x9a\x41\xae\x0a\x84\xf6\xcc\x1a\xe3\x41\x2a\x8b\xc2\x1b\xbb\x01\x93\x83\xef\x14\xf3\x16\x91\xc5\x67\xa3\xba\x8e\xe3\xed\x16\x24\xe6\x4a\x23\x0c\xa4\xe2\x05\x0a\x3f\x5a\x58\x5c\x15\x4a\x8f\x84\x45\xee\x71\x00\x75\x4d\x5e\xc3\xfb\x4a\x15\x84\xe9\x7c\x02\x25\x77\x82\x17\x30\x64\x57\xc2\x94\xc8\x7e\x6f\x2d\xad\xa3\x45\x81\x6a\xdd\x78\xee\x7f\xef\xc3\x5b\xa7\x55\xe5\xb9\x57\x46\x87\x74\x56\x69\xdf\x89\x1b\xb0\x9d\x75\x00\xe4\x1f\xe7\x95\x16\x90\x1c\xe5\xae\x6b\x38\xeb\xa2\xaa\xeb\x14\x5a\xe0\x57\x7c\x8d\x89\xf0\x8f\x20\x8c\xf6\xf8\xe8\xd9\xb4\xf9\x9b\x42\x12\x42\xd8\x25\x5f\x21\xd4\x75\x06\x68\xad\xb1\x29\x6c\x63\x00\xa0\xc1\x10\x98\x97\x6d\x16\xf6\x15\x5d\x69\xb4\xc3\x6d\x1d\xcc\xdf\x2b\xb4\x9b\x0c\xee\x95\x96\x4a\x2f\x82\x6b\x0f\x10\x6b\x23\x93\x94\x7d\x21\xe7\x24\x8d\x23\x95\x53\x91\x53\xce\xd2\xd2\x2f\x36\x7b\x44\x41\x60\xb3\x7e\x81\x8c\x00\xa5\xbf\x85\xf0\xff\x4d\x40\xab\x02\xb6\x71\x14\x59\xf4\x95\xd5\xf4\x19\xe0\xc7\x51\xbd\x2b\x92\x81\x79\xa0\x42\xca\x4d\x8d\x76\x9e\x6b\x3f\xa3\xf6\x92\x26\x8d\x79\x78\x36\x3c\x70\xf2\xb5\x43\x2c\xb1\xd0\x25\x6a\x2b\x8c\xce\xd5\xe2\xfc\x49\x0f\xcd\x79\xdd\x6f\xb3\x9b\x8c\xbd\xb3\x66\xb5\xa3\x32\xf9\xd7\x2d\xb5\x67\xfd\x6c\x19\x79\xc5\x3f\xad\x88\x24\x85\x33\xe9\x0a\x76\x6d\xf9\x1a\xad\xe3\xa1\xee\x76\xfb\x0a\x7e\x28\xbf\x04\x76\x59\xad\x02\x65\x96\x93\x0e\xeb\x3a\x8e\x22\xbf\x29\x69\x29\xf7\x87\xce\xdb\x4a\xf8\x00\x37\x2a\x2d\xca\x7e\xbe\xd1\xa8\xeb\x4d\x1e\x4a\x70\x8f\x8c\xfc\x3d\x3a\x7f\xc2\x3f\x1c\xaf\xb8\x17\x4b\x74\xc0\xb5\x04\xe5\x5d\x93\x84\x6b\x4f\x81\x84\xe3\x90\x34\x28\x6e\xc5\x1f\x30\xf9\x76\x7b\x76\x38\xce\x60\x9c\x11\x4d\x8c\xfa\x6d\x9a\x42\x2d\x43\x13\x6b\x8a\x58\xb0\x0b\x29\x6f\x02\x53\xec\x33\x17\x0f\x7c\x41\x13\x65\x1f\xf8\x3d\x16\xad\xbf\xe5\x7a\x81\x30\xbc\xcb\x60\x98\x53\xc8\x90\xbd\x53\x58\x48\xd7\x30\xa1\x72\x58\xf3\xa2\xc2\x9d\xbc\x8e\x96\xb7\xae\x19\x7d\xe7\xec\x63\x7b\xf2\x07\x12\x81\xc9\x41\x70\xa1\x82\xca\xc9\xe7\x4f\xad\xbe\x57\xd8\x64\x3d\xee\x6c\x02\xbc\x2c\x51\xcb\xa4\x73\x98\xc1\xcb\xc3\x57\xc8\xd4\x30\x7f\x0e\x0b\x76\x93\xa4\xec\x3d\x77\xa7\xbb\xca\xa0\x7f\xdc\x40\xdc\x6d\x45\x90\x51\x68\x29\x65\x53\x53\x69\x9f\xa4\x59\x93\x9e\x26\x72\x0e\x77\x77\x6c\xee\x92\x92\x5d\xce\xbe\x24\xe3\x34\xdd\xc7\x25\x97\xf8\x63\x66\x6d\xd3\x45\x60\xe8\x97\xeb\xb7\x85\x69\x70\xd1\xd1\xe8\xa2\x68\xcd\x3e\x5b\x53\xa2\xf5\x9b\x84\x94\x73\xa5\xf4\xa2\xc0\x9f\x48\xdd\xe8\xa7\x9b\xb3\x37\x6a\x6c\x46\x3d\x93\x0b\x6c\x27\x4d\x0e\xc3\xe6\xd1\x68\x2f\xe6\xc1\x5c\x0f\x3a\x36\x4d\xd7\xc1\xee\xbe\xce\x61\xf0\xc2\xb1\x17\x6e\xd0\x01\x34\xc4\x86\x82\x0e\x9e\x38\x8a\x72\x63\xe1\x2e\x03\x25\xc3\x83\x10\x10\x9c\x12\x11\xb2\xab\xb0\x64\x81\x5a\xa8\xeb\xf9\x5b\x97\xa4\xc7\x1a\x42\x36\x77\x73\x4d\x2b\xb4\x97\x51\x0f\xf4\x04\x06\x9f\x2a\x3f\x38\xb2\x06\xd8\x4f\x51\x23\xbb\xde\x94\xf8\x0f\xd8\x69\x10\x17\x52\xce\xc2\xa8\x75\x73\x1d\xa6\xe1\x4e\x4b\x48\x86\x4a\xa6\x29\x9b\xeb\x9b\xe4\x30\xc1\xe2\x80\xed\x54\xe8\xb5\x39\x04\x7e\xaa\x7c\x37\x72\x3f\xfb\x43\xbb\xef\xb9\xeb\xdf\x4c\xbf\xb6\x39\xb3\x66\x73\x42\xa7\xc7\xc0\xe8\xe3\xc0\x63\x5d\xb7\x3b\x36\x7f\x4b\x58\xff\xfb\xa2\x90\xbe\xfe\x6e\x4f\xf4\xee\x2d\x26\x46\x9e\x5d\x87\x13\x52\x7e\xf6\xea\x56\x39\x14\xa8\xbb\x84\xa4\x30\x99\xc0\xb8\x91\x52\xfb\xb0\xac\xd9\x0d\xad\xc9\x47\x5e\x26\xde\xee\xd7\x25\xf2\xe1\x0d\xeb\x84\x7e\x1b\xdf\x32\xe2\x8e\x4d\x0d\x2f\xd0\x09\x4c\x7a\x46\xa2\x22\x7b\x92\x2e\x3d\xc8\x5e\xd8\x83\xec\xbb\xb1\xaf\xcf\x6f\x1b\x44\xde\xc2\x04\x84\xed\x97\xb1\x6d\x6a\x6f\x77\xe0\x5a\xe8\xde\xc6\x3d\xa5\x3d\xdb\x53\x87\xb3\xf0\x5f\x57\xfb\xfb\xaf\x00\x00\x00\xff\xff\xf5\xa2\xaa\xbd\xb8\x0a\x00\x00") func templateDialectGremlinCreateTmplBytes() ([]byte, error) { return bindataRead( @@ -335,7 +359,7 @@ func templateDialectGremlinCreateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/gremlin/create.tmpl", size: 2768, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/gremlin/create.tmpl", size: 2744, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -440,7 +464,7 @@ func templateDialectGremlinGroupTmpl() (*asset, error) { return a, nil } -var _templateDialectGremlinMetaTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\x41\x6b\x1b\x31\x10\x85\xcf\xd1\xaf\x78\x18\x9f\x42\xad\x4d\x73\x6b\x21\x87\x60\x5c\x30\x84\x5c\xda\x7b\x91\xa5\xb7\xbb\xa2\xb2\x64\x24\x39\xc5\x08\xfd\xf7\xa2\x8d\x12\x87\x5e\x7a\xe9\x6d\x67\xbe\xf9\xe6\xad\xa6\x94\xe1\x56\x6c\xc3\xe9\x12\xed\x34\x67\xdc\xdf\x7d\xfe\xb2\x39\x45\x26\xfa\x8c\x6f\x4a\xf3\x10\xc2\x2f\xec\xbd\x96\x78\x74\x0e\xcb\x50\x42\xe3\xf1\x85\x46\x8a\x1f\xb3\x4d\x48\xe1\x1c\x35\xa1\x83\x21\x6c\x82\xb3\x9a\x3e\xd1\xe0\xec\x0d\x23\xf2\x4c\x3c\x9e\x94\x9e\x89\x7b\x79\xf7\x46\x31\x86\xb3\x37\xc2\xfa\x85\x3f\xed\xb7\xbb\xe7\xef\x3b\x8c\xd6\x11\xbd\x17\x43\xc8\x30\x36\x52\xe7\x10\x2f\x08\x23\xf2\x87\xb0\x1c\x49\x29\x6e\x87\x5a\x85\x68\x6f\x80\x0e\x3e\x65\xe5\x73\x82\x27\x0d\x0d\xc6\x10\x31\x45\x1e\x9d\xf5\x30\x56\x39\xea\x9c\x24\x16\xa3\x14\x18\x8e\xd6\x13\xab\x4e\x86\x3e\x39\x1c\x99\xd5\xf0\xbe\x6b\x85\x5a\xc5\x4d\x29\x88\xca\x4f\xc4\xfa\xe7\x27\xac\x89\xaf\x0f\x58\xcb\x9d\x99\x98\x50\x6b\x29\x58\x3b\x75\xa0\x5b\xda\x94\xdb\xee\x62\xd3\xd4\xe6\xda\xb1\xf5\xf7\x69\xef\x5f\x18\x13\x17\x67\xf3\x26\x2d\x4e\x27\x7f\xa9\x37\xc3\x80\xeb\xf6\x5a\x31\x07\x67\xd2\x72\x9b\x94\xa3\xf5\x13\x5e\x89\xa1\x0f\xb9\x95\x8d\x94\x02\x17\x7e\x33\xb6\xb5\xcf\xea\xd8\xd2\x60\x7b\x30\xcd\x44\xe4\xcb\xe9\xfd\xc4\x46\x65\x75\x50\x89\xf2\xf5\x47\xe9\x12\xff\x77\xf6\x3f\x33\xbd\xb9\x5e\xea\x1a\xf7\x80\x55\xab\x29\x9f\x7a\x67\x25\x3e\x4e\xf7\xcf\x5a\xc5\x9f\x00\x00\x00\xff\xff\x83\xd2\xed\x4f\xc0\x02\x00\x00") +var _templateDialectGremlinMetaTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\x41\x6b\x1b\x31\x14\x84\xcf\xd1\xaf\x18\x8c\x4f\xa1\xde\x4d\x73\x6b\x21\x87\x60\x5c\x30\x84\x5c\xda\x7b\x91\xa5\xd9\x5d\x51\x59\x32\x7a\x72\x8a\x11\xfa\xef\x45\x9b\x4d\x9c\x43\xa1\x97\xde\xf4\xde\xf7\x66\x66\x77\x4a\xe9\x6f\xd5\x36\x9e\x2e\xc9\x8d\x53\xc6\xfd\xdd\xe7\x2f\x9b\x53\xa2\x30\x64\x7c\xd3\x86\x87\x18\x7f\x61\x1f\x4c\x87\x47\xef\x31\x1f\x09\x1a\x4f\x2f\xb4\x9d\xfa\x31\x39\x81\xc4\x73\x32\x84\x89\x96\x70\x02\xef\x0c\x83\xd0\xe2\x1c\x2c\x13\xf2\x44\x3c\x9e\xb4\x99\x88\xfb\xee\xee\x8d\x62\x88\xe7\x60\x95\x0b\x33\x7f\xda\x6f\x77\xcf\xdf\x77\x18\x9c\x27\x96\x5d\x8a\x31\xc3\xba\x44\x93\x63\xba\x20\x0e\xc8\x1f\xc2\x72\x22\x3b\x75\xdb\xd7\xaa\x54\xfb\x07\x98\x18\x24\xeb\x90\x05\x81\xb4\xb4\x18\x62\xc2\x98\x78\xf4\x2e\xc0\x3a\xed\x69\xb2\x74\x98\x15\xa5\xc0\x72\x70\x81\x58\x2d\xa4\x5f\x2e\xfb\x23\xb3\xee\xdf\xbd\x56\xa8\x55\xdd\x94\x82\xa4\xc3\x48\xac\x7f\x7e\xc2\x9a\xf8\xfa\x80\x75\xb7\xb3\x23\x05\xb5\x96\x82\xb5\xd7\x07\xfa\x79\xcd\xee\xa9\xbd\xb7\x8b\x01\x36\x4d\xdf\x0c\xdc\xd0\xe0\x5e\xf6\xe1\x85\x49\x38\x0b\x37\x6f\xca\x59\xb8\x90\xbf\xe9\x6f\xfa\x1e\xd7\x9c\x5a\x31\x45\x6f\x65\x6e\x49\x72\x72\x61\xc4\x2b\xb1\x0c\x31\xb7\xb1\x91\x52\xe0\xe3\x6f\xa6\xe6\xfd\xac\x8f\x2d\x12\x6e\x49\xa7\x1d\x89\x7c\x39\xbd\x97\x6d\x75\xd6\x07\x2d\xec\x5e\xbf\x96\x5e\xf8\xbf\xb3\xff\x99\x19\xec\xb5\xae\x6b\xdc\x03\x56\x6d\x5e\x8a\x45\xad\x2b\xf5\xf1\x7a\x79\xd6\xaa\xfe\x04\x00\x00\xff\xff\xb1\x73\xa1\x6f\xca\x02\x00\x00") func templateDialectGremlinMetaTmplBytes() ([]byte, error) { return bindataRead( @@ -455,7 +479,7 @@ func templateDialectGremlinMetaTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/gremlin/meta.tmpl", size: 704, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/gremlin/meta.tmpl", size: 714, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -480,7 +504,7 @@ func templateDialectGremlinOpenTmpl() (*asset, error) { return a, nil } -var _templateDialectGremlinPredicateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x56\x5f\x6b\xeb\xb8\x13\x7d\xb6\x3f\xc5\x10\x0a\x3f\x3b\xa4\x4a\x7f\xf7\x6d\x17\xfa\xd0\xdb\xcd\x65\x03\x97\x86\xa5\x97\xee\x43\x29\x41\xb5\xc6\x89\xa8\x2a\x99\x91\xec\x72\x31\xfe\xee\x8b\x24\x27\x71\xd2\x5c\xd2\x6d\xf7\x0f\xfb\x94\xa0\x19\xcd\x9c\x39\xe7\x58\x52\xdb\x4e\xc7\xe9\xb5\xa9\xbe\x93\x5c\xad\x1d\x7c\xba\xf8\xff\x4f\xe7\x15\xa1\x45\xed\xe0\x0b\x2f\xf0\xd1\x98\x27\x98\xeb\x82\xc1\x95\x52\x10\x92\x2c\xf8\x38\x35\x28\x58\xfa\x6d\x2d\x2d\x58\x53\x53\x81\x50\x18\x81\x20\x2d\x28\x59\xa0\xb6\x28\xa0\xd6\x02\x09\xdc\x1a\xe1\xaa\xe2\xc5\x1a\xe1\x13\xbb\xd8\x44\xa1\x34\xb5\x16\xa9\xd4\x21\xfe\x75\x7e\x3d\xbb\xb9\x9d\x41\x29\x15\x42\xbf\x46\xc6\x38\x10\x92\xb0\x70\x86\xbe\x83\x29\xc1\x0d\x9a\x39\x42\x64\xe9\x78\xda\x75\x69\xda\xb6\x20\xb0\x94\x1a\x61\x24\x24\x57\x58\xb8\xe9\x8a\xf0\x59\x49\x3d\xad\x08\x85\x2c\xb8\xc3\xa9\x14\x23\x38\xef\xba\x34\x29\x6b\x5d\x64\x0e\xc6\xc2\x2a\xf6\x8d\x78\x83\x64\xb9\xca\xa1\x4d\x93\xc4\xb1\x5f\xb9\x9d\xff\x92\x49\x91\xa7\x49\x97\xb6\xed\x39\xa0\x16\xf0\x27\x7a\x4c\x4d\x65\xfb\x3e\x7e\xf7\x99\xa9\xe0\xe7\x4b\x38\x63\xb7\x85\xa9\x90\x2d\xaa\x41\x88\xd3\x6a\x18\xbb\xa2\xd5\x20\x68\x9d\x21\xbe\xc2\x61\xc2\x6d\xbf\x74\x6a\x08\xbf\x5f\x96\xbe\x35\xbb\xe3\x24\xb9\x90\x85\x9f\x20\x49\x92\xc6\x97\x7b\xe6\x4f\x98\xdd\x3f\x48\xed\x90\x4a\x5e\x60\xdb\x4d\x40\xa1\xce\xda\x36\x42\xea\xba\x3c\xf7\xc9\xa5\x21\x90\x7e\x03\x71\xbd\x42\x68\x42\xed\x24\x69\xee\xe5\x03\x5c\xc2\x2e\xfb\x5e\x3e\xf8\x40\xd7\x77\xee\xf9\xda\x71\x59\xb1\xb6\x85\x82\x2b\xb5\x1d\x8a\x2d\xaa\x6b\x6f\x15\x4f\x4e\xd7\xf9\xc6\xaf\xe1\x36\x8c\xf9\x7d\xa8\x2c\x42\xd7\xed\xba\xf9\xb5\xd0\x21\x7f\x9f\x42\xa5\x44\x25\x86\x02\x95\x43\x8a\xbf\xf8\xe8\xdb\x5c\x92\x7d\xe5\x8f\xa8\x26\x81\x88\x92\x5d\x1b\x6d\x1d\xd7\x0e\xba\x6e\x02\x15\x9b\xfd\x96\x35\x1f\x01\x78\xe8\xa2\x1f\x81\x3c\x65\xb1\x8f\xbb\x48\x1b\x17\xa4\xb9\x91\x6a\x67\xa4\xd3\x04\x9c\x90\xbc\x39\xaa\x79\x2f\xf9\x56\xde\xe8\xa7\xe8\x80\x4d\xd7\xd0\x34\xb6\xce\xdf\x60\xac\x7d\x64\xf9\x81\x47\xdf\x21\x0f\x8a\x15\x4e\xd7\x7c\x4f\x9d\x3d\x7e\x67\x62\x43\x6e\x88\x29\x8f\x34\xc4\x71\x87\x64\x17\x8e\xc7\x9b\x34\xda\xa7\x8c\x16\xb5\x1b\xd4\xf5\x04\x21\x9b\xdb\xb9\xf6\xba\xf4\x45\x0f\xb7\x5d\xc2\x68\xae\x47\xdb\xd8\x74\x0c\xbc\x31\x52\x40\x21\xa9\xa8\x15\x27\x10\x58\xa1\x16\x58\x48\xb4\x10\x4e\xcb\x64\x08\x2c\xe0\xea\x1b\xbc\x86\xe7\x99\x79\x8b\x4f\xa6\x63\x0f\x56\xba\xff\x59\xe0\x1a\x3c\x45\xf0\x22\xdd\x1a\x2c\xaa\xf2\x9c\xb0\x44\x42\x5d\xe0\x04\x1c\x7f\xc2\x70\xb4\xbb\x17\x03\x0d\x92\x93\xc5\x3e\xaa\x38\xf2\x67\x29\x64\x7f\x62\x39\xf6\xd9\xb8\x75\x50\x32\x02\x1e\x88\xb8\x35\x46\xe2\xbc\x13\x06\xa4\x74\xdd\x6c\x7f\xcb\xab\xf8\x5d\xf6\x17\x7a\xc1\xcf\xfa\x0f\xf8\xe1\x4c\x46\x9d\x96\xfb\x49\x5b\xf9\xdf\xeb\x99\xa3\x95\xf7\xba\xff\x6b\xc6\xda\xf3\x43\x00\xe1\x2d\x45\x58\xc2\x33\x72\x6d\x41\x3a\xb0\x6b\x53\x2b\x01\x8f\xfe\x45\x50\x87\xb7\x83\xd1\x18\x1f\x0b\x08\xdb\x79\xb6\x10\x13\xa9\x27\x60\x6a\xe7\xa9\x5b\x2e\xd9\x5c\xdf\x65\xf9\xc4\xff\x5b\xd4\x2e\x9a\x22\x5c\x7c\xcb\x09\x54\xbb\xbb\xcf\x4b\x6e\xfb\xfb\xaf\xca\xa4\xce\xfb\x7f\xa6\x76\xf9\xe6\xee\x4b\x1c\xfb\x7d\x8d\x84\x59\x88\xf9\x82\x14\xff\x26\xb1\xf8\xa1\x23\x63\xb2\xd4\xf9\x64\x9b\x35\xd7\xc7\x93\x7c\x9b\x98\x15\x7f\x8e\x7d\x01\xd4\x0f\xe4\xf7\xbf\x56\x73\x63\xf8\x93\xb3\x39\x1a\x0e\x74\xea\xab\x8a\xf0\x1c\xfd\x4d\xdf\x17\xd7\xfb\x4f\x36\x3a\x7e\x1b\x93\xfd\xd1\xb3\xe6\x22\xbe\x6c\xb6\x15\x6d\xb8\x55\x8e\x73\x10\x13\x22\x11\x1b\x77\xdc\xe0\x4b\xa4\xad\xca\xa2\xd0\xbe\xd7\x25\xf0\xca\x3b\x3f\x73\x64\x27\x10\xd6\xc3\xed\x44\x3d\x1d\xcb\x25\xbb\x8a\x51\xc6\xd8\x3b\x1f\x01\x86\xfe\x9b\x83\x2f\xe8\x63\x73\x6b\xe3\xde\x32\xf8\x01\xca\x1e\xe4\x10\xc8\x8d\x71\x99\x3b\x04\xf1\x47\x00\x00\x00\xff\xff\xe4\x9f\x80\xd3\xeb\x0c\x00\x00") +var _templateDialectGremlinPredicateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x56\xdf\x6b\xe3\x38\x10\x7e\xb6\xff\x8a\xa1\x14\xce\x0e\xa9\xd2\xdb\xb7\x3b\xe8\x43\xb7\x97\xe5\x02\x4b\xc3\xd1\xa5\xf7\x50\x4a\x50\xa5\x71\x22\xaa\x4a\x46\x92\x5d\x16\xe3\xff\xfd\x90\xe4\x38\x76\x9a\x92\x5e\x7b\x3f\xd8\xa7\x04\xcd\x68\xe6\x9b\xef\xfb\x2c\xa9\x69\x66\x93\xf4\x4a\x97\xdf\x8d\x58\x6f\x1c\x7c\x3a\xff\xf9\x97\xb3\xd2\xa0\x45\xe5\xe0\x0b\x65\xf8\xa0\xf5\x23\x2c\x14\x23\x70\x29\x25\x84\x24\x0b\x3e\x6e\x6a\xe4\x24\xfd\xb6\x11\x16\xac\xae\x0c\x43\x60\x9a\x23\x08\x0b\x52\x30\x54\x16\x39\x54\x8a\xa3\x01\xb7\x41\xb8\x2c\x29\xdb\x20\x7c\x22\xe7\xdb\x28\x14\xba\x52\x3c\x15\x2a\xc4\xbf\x2e\xae\xe6\xd7\x37\x73\x28\x84\x44\xe8\xd6\x8c\xd6\x0e\xb8\x30\xc8\x9c\x36\xdf\x41\x17\xe0\x06\xcd\x9c\x41\x24\xe9\x64\xd6\xb6\x69\xda\x34\xc0\xb1\x10\x0a\xe1\x84\x0b\x2a\x91\xb9\xd9\xda\xe0\x93\x14\x6a\x56\x1a\xe4\x82\x51\x87\x33\xc1\x4f\xe0\xac\x6d\xd3\xa4\xa8\x14\xcb\x1c\x4c\xb8\x95\xe4\x9b\xa1\x35\x1a\x4b\x65\x0e\x4d\x9a\x24\x8e\xfc\x4e\xed\xe2\xb7\x4c\xf0\x3c\x4d\xda\xb4\x69\xce\x00\x15\x87\xbf\xd1\x63\xa6\x4b\xdb\xf5\xf1\xbb\x4f\x75\x09\xbf\x5e\xc0\x29\xb9\x61\xba\x44\xb2\x2c\x07\x21\x6a\xd6\xc3\xd8\xa5\x59\x0f\x82\xd6\x69\x43\xd7\x38\x4c\xb8\xe9\x96\x8e\x0d\xe1\xf7\x8b\xc2\xb7\x26\xb7\xd4\x08\xca\x05\xf3\x13\x24\x49\x52\xfb\x72\x4f\xf4\x11\xb3\xbb\x7b\xa1\x1c\x9a\x82\x32\x6c\xda\x29\x48\x54\x59\xd3\x44\x48\x6d\x9b\xe7\x3e\xb9\xd0\x06\x84\xdf\x60\xa8\x5a\x23\xd4\xa1\x76\x92\xd4\x77\xe2\x1e\x2e\x60\x97\x7d\x27\xee\x7d\xa0\xed\x3a\x77\x7c\xed\xb8\x2c\x49\xd3\x00\xa3\x52\xf6\x43\x91\x65\x79\xe5\xad\xe2\xc9\x69\x5b\xdf\xf8\x25\xdc\x9a\x10\xbf\x0f\xa5\x45\x68\xdb\x5d\x37\xbf\x16\x3a\xe4\xef\x53\xa8\x10\x28\xf9\x50\xa0\x62\x48\xf1\x17\x1f\x7d\x9b\x4b\xb2\xaf\xf4\x01\xe5\x34\x10\x51\x90\x2b\xad\xac\xa3\xca\x41\xdb\x4e\xa1\x24\xf3\x3f\xb2\xfa\x23\x00\xf7\x5d\xf4\x1a\xc8\x63\x16\xfb\xb8\x8b\x94\x76\x41\x9a\x6b\x21\x77\x46\x3a\x4e\xc0\x11\xc9\xeb\x83\x9a\x77\x92\xf7\xf2\x46\x3f\x45\x07\x6c\xbb\x86\xa6\xb1\x75\xfe\x06\x63\x8d\x91\xe5\x7b\x1e\x7d\x87\x3c\xc8\xd7\x38\xdb\xd0\x91\x3a\x23\x7e\xe7\x7c\x4b\x6e\x88\x49\x8f\x34\xc4\x91\x04\xd4\x3d\x9c\x5d\x4e\x3c\xe3\x84\x56\x3e\xef\x64\x59\xb9\x41\x71\xcf\x12\x92\x85\x5d\x28\x2f\x4e\x57\x79\x7f\xdb\x05\x9c\x2c\xd4\x49\x1f\x9b\x4d\x80\xd6\x5a\x70\x60\xc2\xb0\x4a\x52\x03\x1c\x4b\x54\x1c\x99\x40\x0b\xe1\xc8\x4c\x86\xe8\x02\xb8\xae\xc1\x2b\x18\x3d\x47\x6f\x71\xcc\x6c\xe2\x11\x0b\xf7\x93\x05\xaa\xc0\x93\x05\xcf\xc2\x6d\xc0\xa2\x2c\xce\x0c\x16\x68\x50\x31\x9c\x82\xa3\x8f\x18\x0e\x79\xf7\xac\xa1\x46\xe3\x04\x1b\x43\x8b\x73\x7f\x16\x5c\x74\x67\x97\x23\x9f\xb5\xdb\x04\x4d\x23\xea\x81\x9c\xbd\x45\x12\xe7\x3d\x31\x60\xa6\x6d\xe7\xe3\x2d\x2f\xe2\xb7\xd9\x3f\xe8\x0a\x3f\xeb\x7f\xe5\x8c\x53\x11\x15\x5b\x8d\x93\x7a\x23\xbc\xd7\x3d\x07\x2b\x8f\xba\xff\xbf\x16\x1b\x39\x23\x20\xf1\xe6\x32\x58\xc0\x13\x52\x65\x41\x38\xb0\x1b\x5d\x49\x0e\x0f\xfe\x95\x50\x85\xf7\x84\x56\x18\x1f\x10\x08\xfd\x50\x3d\xce\x44\xa8\x29\xe8\xca\x79\xfe\x56\x2b\xb2\x50\xb7\x59\x3e\xf5\xff\x96\x95\x8b\xf6\x08\x97\xe1\x6a\x0a\xe5\xee\x3e\xf4\xe2\xdb\xee\x4e\x2c\x33\xa1\xf2\xee\x9f\xae\x5c\xbe\xbd\x0f\x13\x47\xfe\xdc\xa0\xc1\x2c\xc4\x7c\x41\x13\xff\x26\xb1\xf8\xbe\x37\x63\xb2\x50\xf9\xb4\xcf\x5a\xa8\xc3\x49\xbe\x4d\xcc\x8a\x3f\x87\xbe\x05\xd3\x0d\xe4\xf7\xbf\x94\x74\x6b\xfd\xa3\xb3\x39\x33\x1c\xe8\xd8\xf7\x15\xe1\x39\xf3\x2f\x7d\x69\x54\x8d\x9f\x71\xe6\xf0\x0d\x6d\xec\x6b\x4f\x9d\xf3\xf8\xda\xe9\x2b\xda\x70\xd3\x1c\xe6\x20\x26\x44\x22\xb6\xee\xb8\xc6\xe7\x48\x5b\x99\x45\xa1\x7d\xaf\x0b\xa0\xa5\xb7\x7f\xe6\x8c\x9d\x42\x58\x0f\x37\x96\xe9\xe8\x58\xad\xc8\x65\x8c\x12\x42\xde\xf9\x30\xd0\xe6\xc7\x1c\x7c\x69\x3e\x36\xb7\xd2\xee\x2d\x83\xef\xa1\xec\x40\x0e\x81\x5c\x6b\x97\xb9\x7d\x10\x7f\x05\x00\x00\xff\xff\xc8\x78\xeb\x82\xff\x0c\x00\x00") func templateDialectGremlinPredicateTmplBytes() ([]byte, error) { return bindataRead( @@ -495,12 +519,12 @@ func templateDialectGremlinPredicateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/gremlin/predicate.tmpl", size: 3307, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/gremlin/predicate.tmpl", size: 3327, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateDialectGremlinQueryTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x56\x5f\x4f\x23\xb7\x17\x7d\x9e\xf9\x14\xf7\xb7\x42\x68\x26\xbf\xac\x43\xe9\x53\x17\x51\x09\xd8\xac\x1a\x89\x85\x96\x45\xbc\x54\x55\x65\xec\x3b\x13\x6b\x1d\x7b\xd6\xf6\x64\x83\xa2\xf9\xee\x95\xff\x4c\x18\xfe\x04\xd8\xaa\xf0\xc4\x70\xed\x7b\xce\xf1\xf1\xb1\x9d\xf5\x7a\x32\xca\x4f\x74\x73\x63\x44\x3d\x77\xb0\xbf\xf7\xd3\x2f\xef\x1b\x83\x16\x95\x83\x4f\x94\xe1\xb5\xd6\x5f\x61\xa6\x18\x81\x23\x29\x21\x4c\xb2\xe0\xc7\xcd\x12\x39\xc9\x2f\xe7\xc2\x82\xd5\xad\x61\x08\x4c\x73\x04\x61\x41\x0a\x86\xca\x22\x87\x56\x71\x34\xe0\xe6\x08\x47\x0d\x65\x73\x84\x7d\xb2\xd7\x8f\x42\xa5\x5b\xc5\x73\xa1\xc2\xf8\xe9\xec\x64\x7a\xf6\x65\x0a\x95\x90\x08\xa9\x66\xb4\x76\xc0\x85\x41\xe6\xb4\xb9\x01\x5d\x81\x1b\x90\x39\x83\x48\xf2\xd1\xa4\xeb\xf2\x7c\xbd\x06\x8e\x95\x50\x08\xef\xb8\xa0\x12\x99\x9b\xd4\x06\x17\x52\xa8\xc9\xb7\x16\xcd\xcd\x3b\xe8\x3a\x3f\x69\xe7\xba\x15\xd2\x4b\xfa\x70\x08\x0d\xb5\x8c\x4a\xd8\x21\x5f\x98\x6e\x90\x1c\xa7\x91\x34\xd1\x20\x43\xb1\x8c\x33\x37\xdf\x9b\x76\xcf\x59\xb5\x8a\x41\x71\x67\x6e\xd7\xc1\x68\xc8\xd2\x75\x25\x24\x1d\x47\x52\x16\xcc\xad\x80\x69\xe5\x70\xe5\xc8\x49\xfc\x5b\x42\xf1\xe7\x5f\xa1\x87\x9c\xd1\x05\x42\xd7\x8d\x01\x8d\xd1\xa6\x84\x75\x9e\x19\xb4\x9e\x7f\x37\x61\x90\x0b\xb4\x8d\x56\x16\xd7\x5d\x9e\x85\x75\x8d\xe1\x5a\x28\x2e\x54\x1d\xe6\xdd\xd3\x42\x52\xdb\x1f\x7e\x66\x51\x92\x2b\x2a\x5b\xfc\x4c\x9b\xc2\x99\x16\x4b\x92\xca\x79\x26\x2a\x4f\xf9\x18\x00\x37\xfe\x8b\x4c\x57\xc8\xbc\xf8\x31\xdc\x23\x1d\xfb\x1c\x94\x07\xa1\xfd\x7f\x87\xa0\x84\xf4\xaa\x33\x83\xae\x35\xca\xff\x1b\x16\x93\x67\x5d\x9e\x2d\xa9\xf1\xf0\x8d\x6c\x4d\x30\xfd\x62\xe0\xd9\xb0\x1e\x5c\xf0\xfe\xde\x95\xf5\x58\x1f\xf9\x64\xf4\xa2\xb7\xa4\x78\xb1\x92\x6d\x68\x4c\xab\x4a\xd4\xf7\x37\x34\x95\xcb\xbc\xc7\xda\xd2\x3e\xf6\x24\xf9\x0f\xc7\xe2\x44\xb7\xca\x6d\x09\x86\x50\xee\xf5\xc2\x10\x89\xdf\x20\x05\x7b\xb7\xce\xa7\x8a\x41\x4b\x2e\x90\xf2\x99\x17\xf0\xe3\x96\x4d\x57\xc2\x6e\xb3\xec\x5a\x6b\xf9\x7a\x9e\xfd\x46\xed\x19\xae\xde\xc4\xb5\x8a\x4a\x8b\x5b\x9d\x3b\xd6\x5a\xfe\x1b\xeb\x92\x6c\x18\x71\x2b\xc9\xa5\xa1\x4b\x34\x96\x06\xde\xa5\x5f\x42\x4d\xae\xe2\x2a\x4f\xe9\x35\xca\x80\x4a\x7e\xa7\xec\x2b\xad\xfd\xc5\x44\x42\x35\xae\x79\x8b\x51\xc3\x85\x2c\x61\xab\x9f\xe4\x44\x6a\x85\xde\xbe\x2e\xcf\x2a\x6d\xe0\xef\x31\x34\xe1\xa2\xa5\xaa\xc6\x07\x5d\x8d\x41\x2e\x18\x75\x68\x03\x70\x53\x2c\x63\xa7\xa8\x40\xa2\x7a\x70\x60\xb5\xe1\x68\x4a\xf8\x15\xf6\xa2\x0e\x72\xee\x0b\x9e\xed\x05\x5c\xa1\x39\xf4\x25\x1e\x4f\xd4\xe5\x99\xfd\x2e\x1c\x9b\x83\x14\x0b\xe1\xc6\xa0\xab\xca\xa2\x7b\x6c\xd7\xd3\x84\x07\xb0\xa1\xe1\xc0\x03\x33\x6a\x31\xe2\xf4\x6e\xed\xee\xf6\x80\xb1\xf0\x21\xa8\xbe\xf0\xfa\x8a\x51\x1c\x19\x43\xfa\x80\xff\xc3\x28\x34\x97\x09\xe9\xf9\xce\x05\x75\x73\xf2\x99\xae\x66\xca\xfd\xbc\x5f\x3e\x22\x20\x76\x9d\xfa\x4a\xb1\x01\x8f\xfe\xb6\x4a\x7c\x6b\xf1\xb1\x85\xc6\x91\x83\xb0\x03\xf1\xbb\x84\xc3\xc3\x8d\xe7\x1f\x91\xb7\x4d\xda\xe1\x14\xde\x65\x1e\x5e\x56\x54\x1c\xe2\x93\x3d\x19\xc5\x33\x31\x69\xa8\x9b\xa7\xf7\xdb\x86\x87\x3f\x94\xa1\x46\x85\x86\x3a\xa1\x15\xf8\x8d\x0b\xb3\x74\x05\x14\x6a\xb1\x44\x05\xc8\x6b\x24\x10\xde\xff\xe7\x9e\xff\xc0\x10\x7e\x03\x64\xeb\xf5\x7b\xd8\x09\x2b\xea\x1f\xfe\x29\x0f\xf1\x86\x20\xc8\xb3\x7b\x60\xf8\x8e\xa0\x10\x39\x38\x1d\x74\xd4\x86\x3a\x0c\xa3\x41\x86\xd3\x89\x39\xe2\x0d\x7f\x2c\xf4\xb0\x83\xb7\x21\xcf\xfa\xf3\xf1\xec\x1d\x13\x01\x45\x05\x3b\x48\x8e\x05\x17\xa1\x3b\x5e\x55\x9b\x43\x76\xd8\x1f\x67\x72\xac\xdd\xfc\xc1\x31\xf5\xff\xa3\xbf\x13\xad\xa3\xca\xf9\xe3\x1f\x41\x51\x5a\x4c\xc8\x33\x3b\x53\xfe\xec\xe3\xd3\xf0\x33\x35\x2d\x22\xda\xe5\x4d\x83\x4f\x73\x90\xf3\xd6\x5d\x15\x43\xaa\x27\xa1\xcf\x5b\x37\x7d\x81\x72\x32\x53\xb7\xa0\x31\x38\x83\x08\x0d\x33\x54\x19\xbd\x78\x3e\x43\x34\xc6\x26\x0d\x86\x9e\x3e\x4e\x4a\xf3\x17\xc7\xc9\x37\x0e\xe2\x14\xf6\x75\xe7\x4e\x86\x3c\x9a\xcf\x90\x75\xd4\xb8\x81\x1e\xdf\x79\x27\x3a\x6f\x1d\xc5\x17\x06\x8c\x5c\x3d\xb8\x57\x67\x1f\xcb\xdb\xc0\xa9\xff\x38\x71\x5b\xf8\x5e\x23\x81\x5b\xa8\x36\x89\x7c\x66\x69\x4f\x46\xf2\x9f\x00\x00\x00\xff\xff\xf2\x3c\x0e\x8a\x4c\x0d\x00\x00") +var _templateDialectGremlinQueryTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x56\x5d\x4f\x23\x37\x14\x7d\xce\xfc\x8a\xdb\x15\x42\x33\x69\xd6\xa1\xf4\xa9\x8b\xa8\x04\xd9\xac\x1a\x89\x85\x96\x45\xbc\x54\x55\x65\xec\x3b\x13\x6b\x1d\x7b\xd6\xf6\x64\x83\xa2\xf9\xef\x95\x3f\x26\x0c\x1f\x81\x6c\x25\x78\x62\xb8\xbe\xf7\x9c\x7b\x8f\x8f\xed\xac\xd7\xe3\x61\x36\xd1\xf5\xad\x11\xd5\xdc\xc1\xe1\xc1\x2f\xbf\xbd\xaf\x0d\x5a\x54\x0e\x3e\x51\x86\x37\x5a\x7f\x85\x99\x62\x04\x4e\xa4\x84\x90\x64\xc1\xaf\x9b\x25\x72\x92\x5d\xcd\x85\x05\xab\x1b\xc3\x10\x98\xe6\x08\xc2\x82\x14\x0c\x95\x45\x0e\x8d\xe2\x68\xc0\xcd\x11\x4e\x6a\xca\xe6\x08\x87\xe4\xa0\x5b\x85\x52\x37\x8a\x67\x42\x85\xf5\xb3\xd9\x64\x7a\xfe\x65\x0a\xa5\x90\x08\x29\x66\xb4\x76\xc0\x85\x41\xe6\xb4\xb9\x05\x5d\x82\xeb\x91\x39\x83\x48\xb2\xe1\xb8\x6d\xb3\x6c\xbd\x06\x8e\xa5\x50\x08\xef\xb8\xa0\x12\x99\x1b\x57\x06\x17\x52\xa8\xf1\xb7\x06\xcd\xed\x3b\x68\x5b\x9f\xb4\x77\xd3\x08\xe9\x5b\xfa\x70\x0c\x35\xb5\x8c\x4a\xd8\x23\x5f\x98\xae\x91\x9c\xa6\x95\x94\x68\x90\xa1\x58\xc6\xcc\xcd\xf7\xa6\xdc\x73\x96\x8d\x62\x90\xdf\xcb\x6d\x5b\x18\xf6\x59\xda\xb6\x80\xd4\xc7\x89\x94\x39\x73\x2b\x60\x5a\x39\x5c\x39\x32\x89\x7f\x0b\xc8\xff\xfe\x27\xd4\x90\x73\xba\x40\x68\xdb\x11\xa0\x31\xda\x14\xb0\xce\x06\x06\xad\xe7\xdf\x4f\x18\xe4\x12\x6d\xad\x95\xc5\x75\x9b\x0d\xc2\x5c\x23\xb8\x11\x8a\x0b\x55\x85\xbc\x07\xbd\x90\x54\xf6\x97\xcf\xcc\x0b\x72\x4d\x65\x83\x9f\x69\x9d\x3b\xd3\x60\x41\x52\x38\x1b\x88\xd2\x53\x3e\x05\xc0\x8d\xff\x22\xd3\x15\x32\xdf\xfc\x08\x1e\x90\x8e\xbc\x0f\x8a\xa3\x50\xfe\xd3\x31\x28\x21\x7d\xd7\x03\x83\xae\x31\xca\xff\x1b\x86\xc9\x06\x6d\x36\x58\x52\xe3\xe1\x6b\xd9\x98\x20\xfa\x65\x4f\xb3\x7e\x3c\xa8\xe0\xf5\xbd\xdf\xd6\x53\x75\xe4\x93\xd1\x8b\x4e\x92\x7c\xe7\x4e\xb6\xa1\x31\xad\x4a\x51\x3d\xdc\xd0\x14\x2e\xb2\x0e\x6b\x4b\xf9\xc8\x93\x64\x3f\x6c\x8b\x89\x6e\x94\xdb\x62\x0c\xa1\xdc\xeb\x99\x21\x12\xbf\x81\x0b\x0e\xee\x94\x4f\x11\x83\x96\x5c\x22\xe5\x33\xdf\xc0\x8f\x4b\x36\x5d\x09\xbb\x4d\xb2\x1b\xad\xe5\xeb\x69\xf6\x07\xb5\xe7\xb8\x7a\x13\xd5\x4a\x2a\x2d\x6e\x55\xee\x54\x6b\xf9\x7f\xa4\x4b\x6d\xc3\x90\x5b\x49\xae\x0c\x5d\xa2\xb1\x34\xf0\x2e\xfd\x08\x15\xb9\x8e\x53\x9e\xd1\x1b\x94\x01\x95\xfc\x49\xd9\x57\x5a\xf9\x8b\x89\x84\x68\x9c\x79\x8b\x50\xfd\x41\x96\xb0\x55\x4f\x32\x91\x5a\xa1\x97\xaf\xcd\x06\xa5\x36\xf0\xef\x08\xea\x70\xd1\x52\x55\xe1\xa3\xaa\xda\x20\x17\x8c\x3a\xb4\x01\xb8\xce\x97\xb1\x52\x94\x20\x51\x3d\x3a\xb0\xda\x70\x34\x05\xfc\x0e\x07\xb1\x0f\x72\xe1\x03\x9e\x6d\x07\xae\x50\x1c\xea\x12\x8f\x27\x6a\xb3\x81\xfd\x2e\x1c\x9b\x83\x14\x0b\xe1\x46\xa0\xcb\xd2\xa2\x7b\x6a\xd7\x53\xc2\x23\xd8\x50\x70\xe4\x81\x19\xb5\x18\x71\x3a\xb5\xf6\xf7\x3b\xc0\x18\xf8\x10\xba\xbe\xf4\xfd\xe5\xc3\xb8\x32\x82\xf4\x01\x3f\xc3\x30\x14\x17\x09\xe9\xe5\xca\x05\x75\x73\xf2\x99\xae\x66\xca\xfd\x7a\x58\x3c\xd1\x40\xac\x3a\xf3\x91\x7c\x03\x1e\xf5\x6d\x94\xf8\xd6\xe0\x53\x83\xc6\x95\xa3\xb0\x03\xf1\xbb\x80\xe3\xe3\x8d\xe6\x1f\x91\x37\x75\xda\xe1\x64\xde\x65\x16\x5e\x56\x54\x1c\xe2\x93\x3d\x1e\xc6\x33\x31\xae\xa9\x9b\xa7\xf7\xdb\x86\x87\x3f\x84\xa1\x42\x85\x86\x3a\xa1\x15\xf8\x8d\x0b\x59\xba\x04\x0a\x95\x58\xa2\x02\xe4\x15\x12\x08\xef\xff\x4b\xcf\x7f\x60\x08\xbf\x01\x06\xeb\xf5\x7b\xd8\x0b\x13\x75\x0f\xff\x94\x07\x7b\x43\x68\xc8\xb3\x7b\x60\xf8\x8e\xa0\x10\x39\x38\x1d\xfa\xa8\x0c\x75\x18\x56\x43\x1b\x4e\x27\xe6\x88\xd7\xff\xb1\xd0\xc1\xf6\xde\x86\x6c\xd0\x9d\x8f\x17\xef\x98\x08\x28\x4a\xd8\x43\x72\x2a\xb8\x08\xd5\xf1\xaa\xda\x1c\xb2\xe3\xee\x38\x93\x53\xed\xe6\x8f\x8e\xa9\xff\x1f\xe3\x61\x9d\x68\x65\x1d\x55\xce\xdf\x01\x11\x19\xa5\xc5\x04\x3f\xb3\x33\xe5\x2f\x00\x7c\x9e\x63\xa6\xa6\x79\x84\xbc\xba\xad\x71\x07\x22\x72\xd1\xb8\xeb\xbc\xcf\xf7\x2c\xfe\x45\xe3\xa6\xbb\xce\x40\x66\xea\x0e\x39\xfa\xa8\xe7\xa8\xbe\xa5\x4a\xa3\x17\x2f\x5b\x8a\x46\x17\xa5\xc5\x50\xd3\xb9\x4b\x69\xbe\xb3\xbb\x7c\x61\xcf\x5d\x61\x9b\xf7\xee\x59\xca\xa3\x79\x4b\x59\x47\x8d\xeb\xf5\xe3\x2b\xef\x39\xe9\xad\x9d\xb9\xa3\xdf\xc8\xf5\xa3\x6b\x76\xf6\xb1\xb8\xf3\x9f\x7a\x0d\x03\x6e\x21\x7d\x35\x43\x6e\xe1\xdb\x18\x74\x97\x21\x9f\x75\xe8\x7f\x01\x00\x00\xff\xff\x37\x57\x29\x5a\x6a\x0d\x00\x00") func templateDialectGremlinQueryTmplBytes() ([]byte, error) { return bindataRead( @@ -515,7 +539,7 @@ func templateDialectGremlinQueryTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/gremlin/query.tmpl", size: 3404, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/gremlin/query.tmpl", size: 3434, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -540,7 +564,7 @@ func templateDialectGremlinSelectTmpl() (*asset, error) { return a, nil } -var _templateDialectGremlinUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x58\x5f\x6f\xdb\x38\x12\x7f\x96\x3f\xc5\x9c\xe1\x16\x52\xce\xcb\xa4\xfb\x76\x59\xe4\x80\x36\x75\x6f\x7d\xd8\x4b\xba\x75\x77\xef\xa1\x28\x0c\x46\x1a\xd9\x44\x64\x52\x4b\x52\x6a\x72\x86\xbe\xfb\x81\x7f\x24\x51\xb2\x93\xa6\xed\xfe\x79\x49\x2c\x72\x34\x33\xbf\x99\xdf\x0c\x47\xdc\xef\x4f\x4f\x26\x97\xa2\xbc\x97\x6c\xb3\xd5\xf0\xfd\xd9\x8b\x7f\x7c\x57\x4a\x54\xc8\x35\xbc\xa1\x29\xde\x08\x71\x0b\x4b\x9e\x12\x78\x59\x14\x60\x85\x14\x98\x7d\x59\x63\x46\x26\xef\xb7\x4c\x81\x12\x95\x4c\x11\x52\x91\x21\x30\x05\x05\x4b\x91\x2b\xcc\xa0\xe2\x19\x4a\xd0\x5b\x84\x97\x25\x4d\xb7\x08\xdf\x93\xb3\x76\x17\x72\x51\xf1\x6c\xc2\xb8\xdd\xff\x69\x79\xb9\xb8\x5a\x2d\x20\x67\x05\x82\x5f\x93\x42\x68\xc8\x98\xc4\x54\x0b\x79\x0f\x22\x07\x1d\x18\xd3\x12\x91\x4c\x4e\x4e\x9b\x66\x32\xd9\xef\x21\xc3\x9c\x71\x84\x69\xc6\x68\x81\xa9\x3e\xdd\x48\xdc\x15\x8c\x9f\x56\x65\x46\x35\x4e\xa1\x69\x8c\xd4\xec\xa6\x62\x85\xf1\xe9\xfc\x02\x4a\xaa\x52\x5a\xc0\x8c\xac\x52\x51\x22\x79\xe5\x77\xbc\xa0\xc4\x14\x59\xed\x24\xbb\xdf\xdd\xeb\x5e\x48\x70\x34\xfb\x5b\xaa\x56\x55\x9e\xb3\xbb\x5e\x60\x7a\xcd\x7b\xa3\xff\x43\x29\x8c\xdc\x19\x34\xcd\x7e\x0f\x2c\x77\x6f\xda\x07\xb7\x79\x01\x53\xce\x8a\xa9\x5b\x42\x9e\x99\x37\x27\x79\xc5\x53\x88\x07\xce\x34\x0d\x9c\x84\x30\x9a\x26\x01\x8f\x74\x45\x6b\x8c\x53\x7d\x07\xa9\xe0\x1a\xef\x34\xb9\x74\xff\x13\xa3\xe2\xbb\xc0\xa8\x55\x40\xae\xe8\xce\x7b\x80\x85\x32\xbf\x18\xd7\x9d\xed\x39\xa0\x94\x42\x26\xb0\x9f\x44\x12\x95\xf1\xfd\xb9\x37\x43\xde\xa1\x2a\x05\x57\xb8\x6f\x26\xd1\x6f\x15\xca\xfb\x39\xdc\x30\x9e\x31\xbe\xb1\x72\x23\x77\x89\x7f\x6d\xe4\xc3\x58\x8a\x65\x9d\xed\x84\xfc\x6c\xb4\xc6\xc9\x24\x62\xb9\xf1\xe3\x98\xd6\x4c\x9a\x5f\x64\x71\x87\xa9\xc1\x3c\x87\x91\x27\x73\xc3\xd0\xe4\x07\xfb\xfa\xdf\x2e\x80\xb3\xc2\x40\x89\x24\xea\x4a\x72\xe8\xc2\xee\x91\x4e\xa2\xa6\x35\x36\x07\x71\x6b\x0c\x32\x75\x29\xb8\xd2\x94\xeb\x85\x89\x44\xec\xd4\x89\xdb\xcf\xaa\x19\xe2\x9c\x44\x76\x61\x66\x41\xcc\xc8\xbb\x1e\x82\xdd\x31\x1b\x4d\x63\xc3\x3b\x48\x4a\x2a\x78\xce\x36\xe7\x07\xb0\xdd\xba\x79\x77\x14\x1a\xb3\xf9\x46\x8a\x5d\x9b\x9c\xf8\x28\xfc\xd6\x71\xce\x0a\xef\xb0\xf1\x38\x84\x23\x2d\x16\xce\x0a\x07\xc4\x53\xa3\x97\x91\xa8\xc8\x3b\xa4\xd9\x92\x6b\x93\x20\x2b\xe3\xd8\xfa\xc5\x7c\x8d\x07\x95\xc0\x32\x6b\x9f\x2c\x5f\x93\xf7\xf7\x25\x86\x85\x90\xc0\x49\xa6\x0a\xf2\x5e\xd2\x1a\xa5\xa2\x16\x8a\x31\xfc\x89\xe9\x2d\x90\xab\x6a\x67\x33\x25\x29\xe3\xda\xf9\xaa\x8d\x82\xb4\x5f\x54\x5a\x56\xa9\x76\x11\x28\x25\x66\x63\x7d\xa7\xa7\xa1\xb4\x91\x60\x29\xd5\x48\x8c\xbc\x46\xa5\x8f\xc8\xdb\xe5\x1d\xd5\xe9\x16\x15\x50\x9e\x01\xd3\xca\x29\xa1\x5c\x13\x1f\xd7\x5e\xa9\xad\x8c\x1d\xbd\xc5\xf8\xc3\xc7\x93\x7e\x79\x0e\x67\x73\x03\x9b\x18\x94\x83\x68\xda\xdf\xa7\x27\x90\x52\x85\xa6\xf1\xb9\x2e\x06\xaa\xc4\x94\xe5\x2c\x85\x1a\xa5\xc6\x3b\xb0\xdd\xef\x90\x72\xb5\x31\xb7\x21\xbf\xc6\x2c\x4b\x3a\x55\x1b\xe4\x28\x69\xd1\xaa\xca\x85\x84\x2b\xab\x87\xa5\xa8\x02\x4d\x7d\xce\x3b\x35\x09\xf9\x91\xaa\x9f\xe8\x0d\x16\x36\xbb\xe4\x2d\x4d\x6f\xe9\xc6\x48\x11\xbb\x9a\x4c\xa2\xc8\xe8\x5b\xcf\xa1\xb4\xfd\x92\xf2\x0d\x1e\x90\xb7\x0b\xac\xf2\xa9\x88\xeb\xc4\x45\x2a\x04\x5e\x53\x09\xb1\x2b\x0e\x96\x83\x90\xe3\x0c\xc7\x05\x72\x98\x91\x45\xb6\x41\x95\x38\x3f\x23\x59\xc3\x05\xd4\xe4\xb2\x10\x1c\x0d\x2d\xa3\x68\x0d\x17\x20\x6b\xa7\xa6\xd5\x1c\x69\xa9\xe0\xc3\xc7\x61\x32\x27\x91\x8f\x90\xf3\x79\xb6\x9e\xc3\x2c\x77\xc5\xfa\x86\x61\x91\xa9\xbe\x88\x9d\x3b\x31\x17\x1a\x66\x39\x59\xee\x76\x95\xa6\x37\x05\x26\xe6\xe9\x17\x1b\xd4\xd7\x98\xd3\xaa\xf0\x2c\x34\x25\x5a\xd3\xa2\xc2\x63\xfd\xcb\x3c\xe7\xed\x91\x63\x0d\x41\xd3\xfc\xe0\xe5\xc3\x8a\xed\x92\x9b\x93\x5f\x38\xfb\xad\xf2\xa9\x89\x86\xec\xba\x00\x5a\x96\xc8\xb3\x38\x58\x9c\xc3\xf3\xfe\xc9\xe9\x72\xf4\x3f\xef\x73\x7a\x3c\x9d\x73\x18\x2f\x3b\x77\xdb\x8e\x68\x7b\xc4\x89\xf5\x35\x21\x97\xa2\x32\xbd\x60\xee\x0d\x98\xc2\x38\x87\xf5\x9a\x2c\x55\x5c\x92\xab\xc5\xcf\xf1\x59\x92\x74\x6f\xc6\x57\xf8\x69\x21\xa5\x43\x62\x61\x7f\xbb\x07\xad\xe9\x26\xe9\xe2\xd5\x65\x3c\x8a\x6a\xf2\x56\x8a\x12\xa5\xbe\x8f\x4d\xde\x57\x8c\x6f\x0a\xfc\x12\xf5\x46\x8b\x55\xd5\x27\xc2\x34\x28\xc3\x4a\x94\x2c\x6d\xed\x3c\x96\x6c\x9a\x65\x4f\xcf\xf7\xc3\x09\x8f\x68\x96\xfd\xda\xda\x90\x1d\xdd\x8d\x98\xe0\xf1\x7a\x4d\xec\xe6\x61\x4e\x0f\xb0\x25\x73\x93\xa0\x2e\x27\x6d\x1c\xc9\xaa\xda\xc5\x09\xb9\xc2\x3b\xed\x8a\xe8\x6b\x49\xf6\x3b\xb2\xac\x85\x7c\xc0\xb3\x3f\x93\x68\xf9\x4e\x93\x55\x29\x19\xd7\x79\x3c\xfd\xfb\x05\x3c\xab\xa7\x3d\xfb\x3a\x8f\x3c\xff\xc6\x04\xfc\x06\x06\xae\xd7\xbf\x73\x6e\x9d\x87\x1d\x9b\x3b\x2f\xc7\x07\xcf\xf8\x10\x2a\x90\x4a\x10\xa5\x66\x82\xd3\x02\x72\xdb\x17\x49\x70\x64\xd8\x93\x78\x66\x52\x7d\xdd\x0a\xb9\x03\x84\x4a\x28\x1d\x78\x86\xa6\xf7\x32\xae\x51\xe6\x34\xb5\xc3\xe3\x13\xda\x6e\x50\x0c\x43\xcd\xb6\xe0\x0e\xa6\x23\xe3\xe7\xd1\x4a\x6b\x6b\x2b\x70\xa6\x63\x73\xbf\xf6\x84\xa4\x3c\x25\x82\xc6\xb5\x02\x79\xa0\x38\x81\x7f\xc2\x99\xf3\xa1\x26\x2b\x96\xe1\x22\xcf\x31\xd5\x26\xaf\x6f\x3b\xa1\x40\x9e\x10\x92\x90\xd7\x52\x94\x2e\x65\x47\xb2\x12\x84\x0d\x5d\xd8\xec\x81\x18\x4c\x9c\xee\xbb\x89\x09\x6e\xb6\xa7\x4b\x3e\x0d\xf6\xb8\x19\x33\xcd\x17\x90\xe5\x34\x4c\x9f\x29\xf2\x4c\x4d\x03\xe8\x33\x0c\x41\xf7\xe7\xdf\x0c\xc9\x52\x2d\xb9\x39\x3a\x31\xc8\x50\x60\xec\x02\xa6\xd7\x95\x9e\x86\x9b\xd6\xda\xa1\x31\x74\x7d\xf4\x51\x93\x83\xf8\x9e\x9e\x80\xc4\x9d\xa8\x11\xd0\x62\x75\xfc\x0b\x5c\x0b\xfb\xe5\x43\xf4\x40\xdb\x8a\x91\xac\xec\x4c\x38\xe0\xc7\x70\xf8\x31\xf3\x0c\xcb\x1e\x9e\x66\x9c\x2b\x9f\xd1\x16\xba\xef\x7c\x7c\xc5\x32\xe6\x83\xa3\xe5\xa8\x91\xbf\x12\x7a\xbb\xb0\x25\xce\xdd\x77\x40\xe2\x86\x20\x3b\x71\x04\xf0\xc8\x7f\xb7\x28\xd1\xb0\xe7\x5a\x9a\xbf\x4b\xee\x1b\xed\xf2\xb5\x99\xf8\x6c\x07\xb8\xae\xf4\x60\x31\x49\xba\x49\xc8\x33\x8b\x2c\x35\x4a\xaa\xdd\xc0\xd4\x61\x3f\x9e\xe4\x03\x57\x97\xfc\x0b\x1d\xd5\x5b\x94\x43\x87\x9e\xe6\xcf\x03\xf6\xaf\x2b\xfd\x27\x38\xd0\x75\x71\x33\x39\x76\x0d\x43\x4b\x35\x07\x2d\x7d\x65\xb6\xd4\xf4\x63\xf5\x80\x9a\x9f\xe3\x90\x23\xcf\xb1\x5e\xf5\x70\xbd\xd5\xe4\x65\x96\x0d\xb1\xdb\x2f\xbf\xd8\xcf\xfb\x89\xa3\xc3\x61\x0c\x8f\xbd\xf8\x5e\xf4\xaf\x39\xc6\x3c\xcc\xdc\x1f\xa9\x1a\x7f\x68\x1d\xe7\xf5\x57\x0d\x0d\x6e\x64\x18\x15\xc3\xd0\xd9\xe1\x04\xf0\x05\xe7\xbf\x69\x8d\x8f\x1d\xff\xde\xc2\x1c\x4c\x1c\x9c\x7a\xdf\xe8\xbf\x1e\xc9\x86\x2c\xc6\x9f\x4d\x1d\x90\xaf\x2a\xdf\xbf\x00\xfe\x88\x40\x7f\x50\x34\xcc\x43\x7f\x7e\x34\xcd\x00\xf7\x5f\x85\xfa\xe8\xb9\x7e\x70\x0e\x07\x5f\xdd\xb5\x9b\xd0\xfe\x43\xcb\x58\xcb\x0a\x93\xfe\x5e\xad\x6e\x31\x04\x9f\xa2\x8f\x5e\x5f\xf8\xf1\x21\x08\x6c\x30\x3f\xf8\x6e\xb3\xa3\xb7\x08\xaa\x92\x68\x2f\x4a\x75\x77\x35\x91\x09\x54\xb6\x0b\xa6\x82\x6b\xca\x38\xec\x84\x95\xa1\x1c\x8c\x9f\xfe\xda\x80\xe5\xf0\x09\x61\x4b\xeb\xc1\x35\x89\x6f\x5a\x6d\x51\xdb\x5e\xda\x5d\x29\x7c\x6b\x55\x3f\x92\xc6\x7f\xbd\x8f\x5f\x84\x59\x7c\xde\x07\xc4\xde\xbd\xed\x77\x6a\x73\x0e\x53\xdf\x60\x7b\xac\x1e\xa2\x3a\x8a\x71\xda\x3c\x9c\xd4\xa8\x86\x8b\x00\xb8\xfa\x70\xf6\xd1\x5e\x4e\x90\x4b\x41\x0b\x54\x29\xc6\xa3\x4d\xe3\xef\x1c\xec\x6d\x45\x7b\xcf\x91\xca\xbe\xad\x87\xd2\x2f\xce\x3f\xfa\x61\xd3\x1a\x91\x63\xc5\x72\xa0\xec\x08\xab\x0e\x8f\x1a\x23\xea\xaf\xdf\xcc\x07\xc4\xbf\x05\xe3\x66\xc3\x0c\x89\x13\x7b\xbf\xec\x5f\xfd\x7f\x00\x00\x00\xff\xff\x54\x02\x04\x30\xc9\x17\x00\x00") +var _templateDialectGremlinUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x58\x5f\x73\xdb\x36\x12\x7f\x96\x3e\xc5\x56\xa3\x64\x48\x9f\x0a\x3b\x7d\x3b\xdf\xf8\x66\x12\x5b\x69\x75\xd3\xda\x69\x9c\xeb\x3d\x64\x32\x1e\x98\x5c\x4a\x18\x53\x80\x0a\x80\x8c\x7d\x1e\x7e\xf7\x9b\x05\x40\x12\x94\x64\xc7\x4e\x7a\xed\x4b\x62\x01\xcb\xfd\xf7\xfb\xed\x62\x81\xfb\xfb\xc3\x83\xf1\xa9\xda\xdc\x69\xb1\x5c\x59\xf8\xe1\xe8\xd5\xdf\xbf\xdf\x68\x34\x28\x2d\xbc\xe5\x19\x5e\x2b\x75\x03\x0b\x99\x31\x78\x5d\x96\xe0\x84\x0c\xd0\xbe\xae\x31\x67\xe3\x0f\x2b\x61\xc0\xa8\x4a\x67\x08\x99\xca\x11\x84\x81\x52\x64\x28\x0d\xe6\x50\xc9\x1c\x35\xd8\x15\xc2\xeb\x0d\xcf\x56\x08\x3f\xb0\xa3\x76\x17\x0a\x55\xc9\x7c\x2c\xa4\xdb\xff\x79\x71\x3a\x3f\xbf\x9c\x43\x21\x4a\x84\xb0\xa6\x95\xb2\x90\x0b\x8d\x99\x55\xfa\x0e\x54\x01\x36\x32\x66\x35\x22\x1b\x1f\x1c\x36\xcd\x78\x7c\x7f\x0f\x39\x16\x42\x22\x4c\x72\xc1\x4b\xcc\xec\xe1\x52\xe3\xba\x14\xf2\xb0\xda\xe4\xdc\xe2\x04\x9a\x86\xa4\xa6\xd7\x95\x28\xc9\xa7\xe3\x13\xd8\x70\x93\xf1\x12\xa6\xec\x32\x53\x1b\x64\x6f\xc2\x4e\x10\xd4\x98\xa1\xa8\xbd\x64\xf7\x77\xf7\x79\x10\x5a\x57\x96\x5b\xa1\xa4\x53\xa7\x85\xb4\xd1\x77\x13\xd6\xee\x76\xc6\x95\x44\x92\x5c\x71\x73\x59\x15\x85\xb8\xed\xf5\x4d\x2e\x64\xef\xe3\x7f\x51\x2b\x92\x3b\x82\xa6\xb9\xbf\x07\x51\xf8\x2f\xdd\x0f\xbf\x79\x02\x13\x29\xca\x89\x5f\x42\x99\xd3\x97\xe3\xa2\x92\x19\x24\x03\xdf\x9b\x06\x0e\xe2\xa8\x9b\x26\x85\x90\x98\x4b\x5e\x63\x92\xd9\x5b\xc8\x94\xb4\x78\x6b\xd9\xa9\xff\x3f\x25\x15\xdf\x47\x46\x9d\x02\x76\xce\xd7\xc1\x03\x2c\x0d\xfd\x25\xa4\xed\x6c\xcf\x00\xb5\x56\x3a\x85\xfb\xf1\x48\xa3\x21\xdf\x5f\x06\x33\xec\x3d\x9a\x8d\x92\x06\xef\x9b\xf1\x68\xa8\x78\x3c\x1a\x89\x7c\x06\xea\x86\xe4\x07\xd9\x6c\x1a\xe6\x8c\x2e\xce\xd8\x2f\x61\xed\x47\xb4\xd0\x34\x49\x4a\x1f\x15\xf0\x9d\xba\x21\x5b\xa3\x91\x46\x5b\x69\x09\x5d\x62\xc8\x97\x62\x6d\xd9\x9c\xfc\x29\x92\xc9\x5a\x18\x23\xe4\x12\xe2\x18\xd8\xe2\x0c\x0a\xa5\x21\x30\x83\x54\x92\x2f\xbf\x57\xa8\xef\x66\x70\x2d\x64\x2e\xe4\xd2\xb4\x4e\x45\xb9\x64\x21\xa6\x44\xe4\x29\xfb\x95\xc4\xc9\x1f\x0a\x2a\xe4\xe4\x79\x5a\xb6\x75\x78\x18\x29\x3c\xd4\x7a\xdf\x87\xb9\xa6\xbf\xd8\xfc\x16\x33\x42\x6e\x06\x5b\xc6\x66\x54\x96\xe9\x3f\xdc\xe7\xdf\x9d\x80\x14\xa5\x4b\xd2\xbe\x1c\xa1\xd6\xe3\x51\x67\xac\x05\x41\x98\x53\x25\x8d\xe5\xd2\xba\xfc\x25\x5e\x5d\xc8\xf5\x63\x6a\x76\x80\xa5\x85\xa9\x0b\x62\xca\xde\xf7\x21\xb8\x1d\xda\x68\x1a\x47\x92\x01\xb5\x32\x25\x0b\xb1\x3c\xde\x09\xdb\xaf\x37\x1e\xf9\x38\x35\xb4\xf9\x56\xab\x75\x4b\xb1\x64\x6f\xf8\xad\xe3\x52\x94\xc1\x61\x07\x77\x14\x8e\x76\xb1\x48\x51\x6e\x83\x19\x64\x34\x1a\xf6\x1e\x79\xbe\x90\x76\x0b\xac\x67\x57\x5d\x32\xa8\x67\x91\x43\xcb\xf3\x0f\x77\x1b\x8c\xcb\x39\x85\x83\xdc\x94\xec\x83\xe6\x35\x6a\xc3\x5d\x28\x64\xf8\xb3\xb0\x2b\x60\xe7\xd5\xda\x21\xa5\x39\xf5\x1c\xe7\xab\x25\x05\x59\xbf\x68\xac\xae\x32\xeb\x33\xb0\xd1\x98\x6f\xeb\x3b\x3c\x8c\xa5\x49\x42\x64\xdc\x22\x23\x79\x8b\xc6\xee\x91\x77\xcb\x6b\x6e\xb3\x15\x1a\xe0\x32\x07\x61\x8d\x57\xc2\xa5\x65\x21\xaf\xbd\x52\x47\xfe\x35\xbf\xc1\xe4\xe3\xa7\x83\x7e\x79\x06\x47\x33\x0a\x9b\x51\x94\x43\xea\xd3\xdf\x87\x07\x90\x71\x83\xd4\xed\x7d\x81\x82\xd9\x60\x26\x0a\x91\x41\x8d\xda\xe2\x2d\xb8\x96\xbf\x4b\xb9\x9a\xcc\x2d\xd9\x6f\x54\x9d\x9d\xaa\x25\x4a\xd4\xbc\x6c\x55\x51\xd9\x9f\x3b\x3d\x22\x43\x13\x69\xea\x31\xef\xd4\xa4\xec\x27\x6e\x7e\xe6\xd7\x58\x3a\x74\xd9\x3b\x9e\xdd\xf0\xa5\x6b\x20\x6e\x95\xfa\x06\xe9\xbb\x9a\xc1\xc6\x1d\x12\x5c\x2e\x71\x87\xbc\x5d\x62\x4d\x80\x22\xa9\x43\xc3\x89\x03\xaf\xb9\x86\xc4\x17\x87\x28\x40\xe9\x6d\x84\x93\x12\x25\x4c\xd9\x3c\x5f\xa2\x49\xbd\x9f\x23\x5d\xc3\x09\xd4\xec\xb4\x54\x12\x5d\x5f\x1c\x5d\xc1\x09\xe8\xda\xab\x69\x35\x8f\xac\x36\xf0\xf1\xd3\x10\xcc\xf1\x28\x64\xc8\xfb\x3c\xbd\x9a\xc1\xb4\xf0\xc5\xfa\x56\x60\x99\x9b\xbe\x88\xbd\x3b\x89\x54\x16\xa6\x05\x5b\xac\xa9\x47\x5f\x97\x98\xd2\xaf\x7f\xbb\xa4\x9e\x61\xc1\xab\x32\xb0\x90\x4a\xb4\xe6\x65\x85\x8f\xf5\xf5\x62\xa7\xab\x77\x4d\xa6\x33\x4a\xea\xa5\xf8\xbd\x0a\xa8\x8c\x86\xc4\x3a\x01\xbe\xd9\xa0\xcc\x93\x68\x71\x06\x2f\xfb\x5f\x5e\x97\x67\xfe\x71\x0f\xe7\x7e\x24\x67\xb0\xbd\xec\xbd\x6c\x9b\xa1\x6b\x0f\x2e\xaa\x94\x9d\xaa\x8a\xba\xc0\x2c\xe8\xa7\x92\x38\x86\xab\x2b\xb6\x30\xc9\x86\x9d\xcf\x7f\x4d\x8e\xd2\xb4\xfb\x30\x39\xc7\xcf\x73\xad\x7d\x20\x2e\xb3\xdf\xec\x40\x6b\xb9\x49\xbb\x6c\x75\x50\x8f\x46\x35\x7b\xa7\xd5\x06\xb5\xbd\x4b\x08\xf0\x4b\x21\x97\x25\x3e\x43\x3b\x29\x71\x9a\x7a\x14\xa8\x31\x11\x1b\x51\x8b\xac\x35\xf3\x25\x90\x5f\xe7\x39\xe6\xde\xc8\xa5\x6b\x43\x2e\xf6\x6d\xa4\x1f\x86\x7a\xc4\xf3\xfc\x37\x32\xe0\xea\xaa\xe3\x38\x89\x29\x99\x5c\x5d\x31\xb7\xb9\x8b\xe6\x4e\x5c\xe9\x8c\xb0\xe9\xe0\x08\x29\x64\x97\xd5\x3a\x49\xd9\x39\xde\x5a\x5f\x38\x5f\xcb\xae\x3f\x90\x5e\x6d\xc4\x3b\x0c\xfb\x33\x29\x46\x93\xd3\xa5\x9b\x63\x8b\x64\xf2\xb7\x13\x78\x51\x4f\x3a\xde\x75\x0e\x05\xe6\x6d\x53\xef\x1b\xb8\x77\x75\xf5\xc7\x22\xeb\x1d\xec\x78\xdc\x39\xb9\x7d\xd4\x6c\x1f\x3b\x25\x72\x0d\x6a\x43\x2c\xe6\x25\x14\xae\x13\xb2\xe8\x90\x70\x67\xef\x94\x80\xbe\x68\x85\xfc\x91\xc1\x35\x6c\x7c\xec\x02\xa9\xdb\x0a\x69\x51\x17\x3c\x73\x43\xef\x13\x1a\x6d\x54\x09\x43\xcd\xae\xd4\xf6\xb7\xd0\x61\x61\x9d\x92\xef\x98\x27\x69\x5b\x5b\x91\x3f\x1d\x9d\xfb\xb5\x27\xc0\xf2\x94\x24\x92\x77\x25\xca\x48\x71\x0a\xff\x84\x23\xef\x43\xcd\x2e\x45\x8e\xf3\xa2\xc0\xcc\x12\xb2\xef\x3a\xa1\x48\x9e\x31\x96\xb2\x33\xad\x36\x1e\xb5\x3d\xc0\x44\x99\x43\x9f\x39\x77\x0a\x46\x63\xa6\xbf\x21\x86\x5b\xd8\x64\xe1\xaf\x5b\x61\x4f\xd2\x6c\xd9\x5e\xce\x0a\x98\xbc\x30\xec\x85\x99\x44\xa1\x4f\xd1\xd7\x47\x14\x79\x7f\xf2\x4d\x91\x2d\xcc\x42\xd2\xa1\x89\x11\x52\x91\xc5\x13\x98\x5c\x54\x76\x12\x6f\x3a\x93\xbb\x16\xd1\x77\xd2\x2f\xdb\x1d\x64\xfa\xf0\x00\x34\xae\x55\x8d\x80\x2e\x6a\x4f\xc6\xc8\xbf\xb8\x73\x3e\xc0\x15\x7c\x94\x2b\xc3\xe9\x27\x0c\x34\x22\x1f\x4e\x34\xb1\xca\xf7\xce\x9f\x7c\x9f\xe6\xc5\x99\x89\xb5\xc6\x81\x78\x6f\xdf\x88\x5c\x84\x5c\x59\xbd\xd5\xdc\xdf\x28\xbb\x9a\xbb\xc2\x97\xfe\x42\x90\xfa\x69\xc8\x8d\x1e\x51\xa0\xec\x3f\x2b\xd4\x48\x8c\xba\xd0\xf4\xef\x42\x86\xee\xbb\x38\xa3\xd1\xcf\xf5\x85\x8b\xca\x0e\x16\xd3\xb4\x1b\x89\x02\xdb\xd8\xc2\xa2\xe6\xd6\x4f\x4e\x5d\x0e\xf6\x63\xbe\xe3\xea\x42\x3e\xd3\x51\xbb\x42\x3d\x74\xe8\x69\xfe\x3c\x60\xff\xa2\xb2\x7f\x82\x03\x5d\x6f\xa7\x11\xb2\x6b\x22\x56\x9b\x19\x58\xdd\xde\x9a\x03\x49\xc3\x7c\x3d\x20\xe9\x13\xb8\xf4\x65\x12\xed\x47\xa4\xa6\x11\x63\x98\x02\x77\x13\x4c\xc2\xfc\x9f\x7a\x56\xec\xa6\x72\xdf\x87\x1f\x54\xff\x99\x27\xce\xc3\x04\xfe\x89\x9b\xed\x8b\xd7\x7e\x7a\x7f\xd5\x40\xe1\xc7\x89\xad\x9a\x18\x3a\x3b\x9c\x0e\x9e\x31\x1b\x50\xd7\x7c\x6c\x34\x08\x16\x08\xaf\xf6\xac\x0f\x67\xc0\xd7\x47\xb2\x64\xf3\xed\x6b\x54\x17\xc8\x57\x55\xf1\x5f\x10\xfe\x16\x81\xfe\x4f\xd9\xa0\x1f\xfd\xa9\xd2\x34\x83\xb8\xff\xaa\xa8\xf7\x1e\xf9\x3b\x47\x74\x74\x0b\xaf\xfd\xf8\xf6\x0b\xdf\x24\x56\x57\x98\xf6\xaf\x85\x75\x1b\x43\x74\x35\x7d\xf4\x39\x23\x4c\x16\x51\x62\xa3\xd1\x22\x34\x9d\x35\xbf\x41\x30\x95\x46\xf7\x5a\x6c\xbb\xa7\x8a\x5c\xa1\x71\xcd\x30\x53\xd2\x72\x21\x61\xad\x9c\x0c\x97\x40\x7e\x86\x67\x04\x51\xc0\x67\x84\x15\xaf\x07\xcf\x26\xa1\x77\xb5\x45\xed\x5a\x6a\xf7\xc4\xf0\xad\x55\xfd\x08\x8c\x3f\x7e\x48\x5e\xc5\x28\xbe\xec\x13\xe2\xde\xe2\xee\xd7\x66\x79\x0c\x93\xd0\x67\xfb\x58\x43\x88\x66\x6f\x8c\x93\xe6\x61\x50\x47\x35\x9c\x44\x81\x9b\x8f\x47\x9f\xdc\x63\x05\x3b\x55\xbc\x44\x93\x61\xb2\xb5\x49\xfe\xce\xc0\xbd\x5e\xb4\xad\x3d\xd3\x7d\x6b\x8f\xa5\x5f\x1d\x7f\x0a\x73\xa8\x33\xa2\xb7\x15\xeb\x81\xb2\x3d\xac\xda\x3d\x71\x48\x34\x3c\xc7\xd1\xed\xe2\x5f\x4a\x48\xda\xa0\xf9\x71\xec\x5e\xcd\xc3\xa7\xff\x0b\x00\x00\xff\xff\xc6\xcb\x74\xa4\xce\x18\x00\x00") func templateDialectGremlinUpdateTmplBytes() ([]byte, error) { return bindataRead( @@ -555,7 +579,7 @@ func templateDialectGremlinUpdateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/gremlin/update.tmpl", size: 6089, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/gremlin/update.tmpl", size: 6350, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -580,7 +604,7 @@ func templateDialectSqlByTmpl() (*asset, error) { return a, nil } -var _templateDialectSqlCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x55\x5d\x4f\x2b\x37\x10\x7d\xde\xfd\x15\xd3\x28\xaa\x76\xa3\x65\xc3\x45\x55\xa5\x82\x52\xe9\x96\x80\x14\xe9\x0a\xb5\x0d\xf4\xa1\x2f\x57\x8e\x3d\x9b\x58\x38\xf6\x62\x7b\x53\x50\xe4\xff\x5e\x8d\xbd\x0b\x21\x80\x2e\x2f\xe0\x78\xbe\xce\x9c\x19\x9f\xdd\xef\xa7\x93\xfc\xd2\xb4\x4f\x56\xae\x37\x1e\xce\x4e\xbf\xfc\x76\xd2\x5a\x74\xa8\x3d\x5c\x33\x8e\x2b\x63\xee\x61\xa1\x79\x0d\x5f\x95\x82\xe8\xe4\x80\xec\x76\x87\xa2\xce\x6f\x37\xd2\x81\x33\x9d\xe5\x08\xdc\x08\x04\xe9\x40\x49\x8e\xda\xa1\x80\x4e\x0b\xb4\xe0\x37\x08\x5f\x5b\xc6\x37\x08\x67\xf5\xe9\x60\x85\xc6\x74\x5a\xe4\x52\x47\xfb\xb7\xc5\xe5\xd5\xcd\xf2\x0a\x1a\xa9\x10\xfa\x3b\x6b\x8c\x07\x21\x2d\x72\x6f\xec\x13\x98\x06\xfc\x41\x31\x6f\x11\xeb\x7c\x32\x0d\x21\xcf\xf7\x7b\x10\xd8\x48\x8d\x30\x12\x92\x29\xe4\x7e\xea\x1e\xd4\x94\x5b\x64\x1e\x47\x10\x02\x79\x8c\x57\x9d\x54\x84\xe7\x7c\x06\x2d\x73\x9c\x29\x18\xd7\x4b\x6e\x5a\xac\xff\xe8\x2d\xbd\xa3\x45\x8e\x72\x97\x3c\x9f\xcf\xcf\xe1\x54\xb0\xe9\x34\x87\xe2\x95\x6f\x08\x30\x39\xac\x12\x42\x09\xee\x41\x2d\xd9\x0e\x0b\xee\x1f\x81\x1b\xed\xf1\xd1\xd7\x97\xe9\x7f\x09\x45\x74\xaf\x6f\xd8\x16\x21\x84\x0a\xd0\x5a\x63\x4b\xd8\xe7\xd9\x8e\x59\x28\xf2\x2c\x8b\xf6\xbf\x0f\x0a\xcc\xe0\xe7\xc3\x98\x3d\x37\xba\x91\xeb\x73\x38\x02\x52\xa7\xfb\x90\x67\xd9\x77\xd7\x22\xa7\x38\xf7\xa0\xd6\x96\xb5\x9b\xfa\x32\x92\xb2\x6c\x91\xef\xf3\x2c\xcb\x6e\xd9\x4a\x61\xca\x50\xff\xc9\xf8\x3d\x5b\x53\xe6\x3a\x5e\x57\xe4\xb0\x98\x9f\x1f\x44\x5f\x4b\x54\xe2\x39\x38\xbb\x7d\x6a\xf1\x1c\x1a\xba\xac\x63\x8a\xc5\xbc\xa6\x3b\xea\xd2\xf9\xa1\xb5\xe8\x7a\x69\x54\xb7\xd5\x6f\x2b\x0d\x61\x31\x82\x69\x3f\x04\xc4\xbf\x21\xcf\xca\x3c\xdb\xef\x4f\x40\x36\xc9\xed\xce\xa1\x9d\xc7\x59\x0b\x9a\x44\x96\xc9\x06\x76\x4c\x75\x48\xc3\x3a\xe6\x61\xc8\xdd\xcf\x37\x82\x87\x10\x2e\xfa\x88\x9f\x66\xa0\xa5\x82\xd8\xca\x31\xd7\xf5\x62\x0e\x33\x98\x44\x47\xb2\x47\x22\x29\xd7\x3f\x31\xf4\xc0\x14\x12\x40\xd4\x09\x10\x9d\x2d\xd3\x6b\x84\xf1\xf7\x0a\xc6\x0d\xe1\x1a\x27\xde\xdc\xe7\x10\x37\x9f\xc1\x9b\xf0\xf4\x69\x67\xc0\xda\x16\xb5\x28\x0e\x6f\xab\xcf\x8f\xad\xf9\x68\x68\xb1\xd9\xf3\xbe\xd7\x1f\xcf\xb1\x79\x3b\xc5\xf2\x5d\x72\x93\xf3\xd2\xdb\x8e\xfb\xa1\x4b\x88\x6c\xc8\x06\xb4\xf1\x64\xbd\x91\x4a\xd1\x16\x42\x08\xf4\x52\x12\xbf\x9f\x23\x1d\x13\xe9\x57\x62\x8d\x2f\x9c\x6b\x23\xd0\x7d\xc4\x39\xbe\xe5\x5c\xa1\x2e\x62\x4c\x09\xbf\xc3\xe9\xb0\x25\x27\xf0\x9f\xf4\x1b\xc0\x47\x4f\xb5\xc7\x30\xa2\x22\x23\x2a\x39\xba\x21\xe7\x11\x78\xdb\x21\x8c\xfe\x45\x6b\x46\x30\xd2\x52\x8d\x12\x82\xc8\x82\xc7\x6d\xab\x98\x3f\xd2\x29\x81\x0d\xc6\x2c\x35\x3d\xea\xfd\x74\xd2\xab\x99\x20\x25\x24\x87\xae\x15\xcc\x63\xed\xb7\xad\x82\xa8\x78\x3d\x94\xa1\xfd\x61\x1d\x52\xc3\x47\xdb\x10\x2f\x2b\xa0\x0a\xe5\x5b\xe6\x64\x43\xc2\x43\xb4\x1c\x29\x04\x75\x43\xc2\x55\xbd\xe1\x4b\x58\x3a\x55\x10\xd3\x97\x17\x31\xfe\x60\x35\x65\x03\x1c\xad\xad\xc0\xdc\x53\x5a\xe9\x96\x7f\x7d\x8b\x6b\x61\x99\xd4\xfe\x8a\x54\xae\x40\x6b\xcb\x0b\x72\x88\xac\x52\x82\x59\x0c\x4a\xf8\x32\x8b\xbe\xb3\x9a\x32\x46\x59\xcc\x07\xd0\xb2\x01\x46\xac\x1f\x0b\x41\x61\x6c\xba\x5c\xb8\xa5\xb7\x52\xaf\x87\x5f\x77\x77\x8b\x79\x99\x28\xa2\xf8\xe9\x04\xe6\x86\xf6\x6b\x23\xf5\xba\x82\x15\x72\xd6\x39\xa4\x8f\x8d\x43\x38\x03\xff\xd4\xa2\x83\x6d\xe7\x3c\xac\x10\x5c\xd7\xb6\x4a\xa2\x80\xd5\x53\xfc\x1c\x75\x0e\x6d\x0d\x93\x29\x9c\x0c\x1b\x87\xca\xe1\x4b\xf2\x0f\x15\x8a\x18\x79\x57\x5e\x66\xfd\x5a\xbd\x1e\xa5\x14\x44\xdb\x6b\xbd\xa9\x0b\xa9\xfd\xaf\xbf\xbc\xff\x98\xa2\x52\xa5\xa7\xf3\x9a\x84\x10\x9c\xb7\xdc\xe8\x5d\x7d\x6d\xec\x96\xf9\x85\xf6\x85\x14\x15\x7c\x39\x2d\xe9\x41\x25\xf4\x87\xb2\x0d\x21\x14\x52\x94\xcf\xaf\xed\xa5\xb3\x77\x69\x4f\x78\xc3\x51\x07\x87\xe7\x7e\x90\xc7\x90\x2b\x1a\x6d\x9e\x3e\xdc\xbd\xeb\xff\x01\x00\x00\xff\xff\x57\x84\x32\x22\x87\x08\x00\x00") +var _templateDialectSqlCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x55\xc1\x6e\xe3\x36\x10\x3d\x4b\x5f\x31\x15\x8c\x42\x32\x1c\x3a\x1b\x14\x05\x9a\x85\x0b\x6c\xe3\xa4\x30\xb0\x0d\xda\x3a\xe9\xa1\x97\x05\x4d\x8e\x6c\x22\x34\xa9\x90\x94\x9b\x40\xd0\xbf\x17\x43\x49\x89\xe2\x24\xbb\x7b\x49\xe8\xe1\x9b\xe1\xe3\x9b\xe1\x53\xd3\xcc\xa7\xe9\x85\xad\x1e\x9d\xda\xee\x02\x9c\x9d\x7e\xf8\xe5\xa4\x72\xe8\xd1\x04\xb8\xe2\x02\x37\xd6\xde\xc1\xca\x08\x06\x9f\xb4\x86\x08\xf2\x40\xfb\xee\x80\x92\xa5\x37\x3b\xe5\xc1\xdb\xda\x09\x04\x61\x25\x82\xf2\xa0\x95\x40\xe3\x51\x42\x6d\x24\x3a\x08\x3b\x84\x4f\x15\x17\x3b\x84\x33\x76\x3a\xec\x42\x69\x6b\x23\x53\x65\xe2\xfe\xe7\xd5\xc5\xe5\xf5\xfa\x12\x4a\xa5\x11\xfa\x98\xb3\x36\x80\x54\x0e\x45\xb0\xee\x11\x6c\x09\x61\x74\x58\x70\x88\x2c\x9d\xce\xdb\x36\x4d\x9b\x06\x24\x96\xca\x20\x64\x52\x71\x8d\x22\xcc\xfd\xbd\x9e\x0b\x87\x3c\x60\x06\x6d\x4b\x88\xc9\xa6\x56\x9a\xf8\x9c\x2f\xa0\xe2\x5e\x70\x0d\x13\xb6\x16\xb6\x42\xf6\x5b\xbf\xd3\x03\x1d\x0a\x54\x87\x0e\xf9\xb4\x7e\x4a\xef\x41\xfb\x3a\xf0\xa0\xac\x89\xe5\x9c\x32\x61\x94\x97\xb1\x61\x37\x03\xc2\xa7\x65\x6d\x04\xe4\x2f\x6a\xb7\x2d\x4c\xc7\xac\xda\xb6\x00\x7f\xaf\xd7\xfc\x80\xb9\x08\x0f\x20\xac\x09\xf8\x10\xd8\x45\xf7\xbf\x80\x3c\xc2\xd9\x35\xdf\x23\xb4\xed\x0c\xd0\x39\xeb\x0a\x68\xd2\xe4\xc0\x1d\xe4\x69\x92\xc4\xfd\xbf\x47\x07\x2c\xe0\xc7\x71\x4e\x23\xac\x29\xd5\xf6\x1c\x8e\x88\xb0\x2e\xde\xa6\x49\xf2\xc5\x57\x28\x28\xcf\xdf\xeb\xad\xe3\xd5\x8e\x5d\x44\x11\xd7\x15\x8a\x26\x4d\x92\xe4\x86\x6f\x34\x76\x15\xd8\x9f\x5c\xdc\xf1\x2d\x55\x66\x31\x3c\x23\xc0\x6a\x79\x3e\xca\xbe\x52\xa8\xe5\x53\x72\x72\xf3\x58\xe1\x39\x94\x14\x64\xb1\xc4\x6a\xc9\x28\x46\xb7\xf4\x61\xb8\x5a\x84\x5e\x58\x5d\xef\xcd\xeb\x93\x86\xb4\x98\xc1\x4d\x18\x12\xe2\xdf\x36\x4d\x8a\x34\x69\x9a\x13\x50\x65\x07\xbb\xf5\xe8\x96\x71\x36\x24\x75\x22\x49\x54\x09\x4a\xce\xc0\xde\x51\xe3\x5e\x34\x72\x54\xfc\x8f\x3e\xf6\x3b\x52\xfd\xbc\xf8\x48\xf8\x78\x85\x63\x8d\xd9\x6a\x09\x0b\x50\x92\xf6\xa2\x78\x94\xfe\x0f\xd7\x35\x0e\xe1\xb6\x23\x84\xa6\x23\x40\x6b\xc7\xcd\x16\x61\xf2\x65\x06\x93\x92\x68\x4c\x3a\x9d\xfc\x13\xc3\x03\x15\xf8\x1a\xc9\xf2\x2b\x14\x3b\x1a\x7d\xc5\x05\xf0\xaa\x42\x23\xf3\x71\x74\xf6\xfd\x1d\x2a\xdf\xeb\x4f\xbc\xe3\x79\xcf\xf4\x9b\x1d\x2b\x5f\xf7\xab\x78\x53\xce\x0e\xbc\x0e\xae\x16\x21\x52\xeb\xe6\xb8\x69\x62\x47\x4b\x76\xad\xb4\xa6\x59\x83\xb6\xa5\xd9\xee\x54\x8d\x24\xbe\x29\x35\x76\x52\x5f\xca\x2d\x3e\x2b\x6d\xac\x44\xff\x9e\xca\x78\x44\x64\xb5\xf4\x24\xb4\x46\x93\xc7\xbc\x02\x7e\x85\xd3\x61\x2e\x4e\xe0\x3f\x15\x76\x80\x0f\x81\xce\x9f\x40\x46\x07\x65\x74\x6c\x76\x4d\xe0\x0c\x82\xab\x11\xb2\x7f\xd1\xd9\x0c\x32\xa3\x74\xd6\xb1\x88\x2a\x04\xdc\x57\x9a\x87\x23\x07\x93\x58\x62\xac\xc2\xe8\xf9\x36\xf3\x69\xef\x73\x92\x3c\x92\x00\x75\x25\x79\x40\x16\xf6\x95\x86\xe8\x85\x3d\x95\x41\x82\x61\x1a\xba\x4b\x1f\x0d\x43\x0c\xce\x80\x4e\x28\x5e\xab\xa7\x4a\xb2\x18\x92\xe6\xc8\x0b\xe8\x36\x64\x51\xb3\x57\x3e\x22\x1d\xad\x66\x10\xcb\x17\x1f\x63\xfe\x0f\x0b\x30\x4a\x47\x91\x54\x09\x02\x9d\x1b\xe6\x5a\xf9\xf5\x5f\x9f\xe3\x58\x38\xae\x4c\xb8\x24\x3f\xcb\xd1\xb9\xd1\x28\x53\x81\x45\x4c\xea\xf8\x25\x0e\x43\xed\x0c\x55\x8c\x06\x98\x0e\xa4\x55\x09\x9c\x54\x3f\x7e\xf2\xb9\x75\x5d\x70\xe5\xd7\xc1\x29\xb3\x1d\x7e\xdd\xde\xae\x96\x45\x27\x11\xe5\xcf\xa7\xb0\xb4\x60\x6c\xd8\x29\xb3\x9d\xc1\x06\x05\xaf\x3d\xd2\x67\xc8\x23\x9c\x41\x78\xac\xd0\xc3\xbe\xf6\x01\x36\x08\xbe\xae\x2a\xad\x50\xc2\xe6\x31\x7e\xa8\x6a\x8f\x8e\xc1\x74\x0e\x27\xc3\xd4\xa1\xf6\xf8\x5c\xfc\x5d\x2f\x22\x45\xde\x34\x94\x45\x3f\x56\x2f\x5b\xa9\x24\xc9\xf6\xd2\x65\x58\xae\x4c\xf8\xf9\xa7\xb7\x1f\x53\xf4\xa6\xfe\xe9\xbc\x10\xa1\x6d\x7d\x70\xc2\x9a\x03\xbb\xb2\x6e\xcf\xc3\xca\x84\x9c\x5c\xf1\xc3\x69\x41\x8f\xaa\x63\x3f\x36\x68\xb2\x18\x25\x8b\xa7\x17\xf7\x7c\xb3\x37\x65\xef\xf8\xb6\x47\x37\x18\xaf\xfb\x46\x1e\x53\x9e\x51\x6b\xd3\xee\x93\xde\x43\xff\x0f\x00\x00\xff\xff\x32\xe3\xa8\xb3\xa1\x08\x00\x00") func templateDialectSqlCreateTmplBytes() ([]byte, error) { return bindataRead( @@ -595,7 +619,7 @@ func templateDialectSqlCreateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/sql/create.tmpl", size: 2183, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/sql/create.tmpl", size: 2209, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -800,7 +824,7 @@ func templateDialectSqlSelectTmpl() (*asset, error) { return a, nil } -var _templateDialectSqlUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x58\x5f\x6f\x1b\x39\x0e\x7f\xb6\x3f\x05\xcf\x08\x0a\xdb\x70\x26\xb9\xbe\x9d\x03\x1f\x90\x26\x29\x60\x5c\x9b\xf6\xea\x76\x1f\x5a\x14\x81\x32\xe2\xd8\x82\x15\x69\x22\x69\xbc\xe9\x1a\xfe\xee\x0b\xea\xcf\x78\xec\xb1\xd3\x76\xbb\xc0\x16\xa8\x3b\xe2\x1f\x91\xfc\x89\xa4\xa8\xae\xd7\x67\xc3\xee\x95\x2e\xbf\x19\x31\x5f\x38\x78\x79\xfe\xef\xff\x9c\x96\x06\x2d\x2a\x07\xaf\x59\x8e\xf7\x5a\x2f\x61\xaa\xf2\x0c\x2e\xa5\x04\x2f\x64\x81\xf8\x66\x85\x3c\xeb\x7e\x5c\x08\x0b\x56\x57\x26\x47\xc8\x35\x47\x10\x16\xa4\xc8\x51\x59\xe4\x50\x29\x8e\x06\xdc\x02\xe1\xb2\x64\xf9\x02\xe1\x65\x76\x9e\xb8\x50\xe8\x4a\xf1\xae\x50\x9e\xff\x66\x7a\x75\x73\x3b\xbb\x81\x42\x48\x84\x48\x33\x5a\x3b\xe0\xc2\x60\xee\xb4\xf9\x06\xba\x00\xd7\x30\xe6\x0c\x62\xd6\x1d\x9e\x6d\x36\xdd\xee\x7a\x0d\x1c\x0b\xa1\x10\x7a\x5c\x30\x89\xb9\x3b\xb3\x8f\xf2\xac\x2a\x39\x73\xd8\x83\xcd\x86\x24\x4e\xca\xe5\x1c\xc6\x13\x38\xc9\x66\xb9\x2e\x31\x7b\xcf\xf2\x25\x9b\x63\xe2\xde\x57\x42\x92\xb7\xe3\x09\x94\xcc\xe6\x4c\xd6\x82\xaf\x22\x27\x0a\x1a\xcc\x51\xac\x82\x64\xfd\x5d\xab\x47\x21\xad\x90\xf8\x0b\x66\x67\x55\x51\x88\xa7\xad\x40\xef\x9d\x4a\x2e\x9d\xc2\xc9\x1f\x68\x34\x09\x9e\xc3\x66\xb3\x5e\x83\x28\x82\xaa\x5f\x04\xe6\x04\x7a\x4a\xc8\x5e\x20\xa1\xe2\xb5\xaa\x41\x47\x9a\x3d\xd5\x3b\xa4\x4b\x5c\x8a\xf5\x43\xf2\xb0\xa9\xdf\x2d\x2a\x95\x43\x7f\x27\x9a\xcd\x06\x86\x4d\x1c\x36\x9b\x01\xd8\x47\x39\x63\x2b\xec\xe7\xee\x09\x72\xad\x1c\x3e\xb9\xec\x2a\xfc\x3b\x48\xea\x8e\x34\x77\xcc\xfb\x6d\xb2\x5b\xf6\x10\x7d\x41\x69\xe9\x4b\x28\x57\x7b\x30\x02\x34\x86\xfe\x6a\x33\x80\x75\xb7\x73\x67\x4b\xcc\x29\x9a\x17\xf6\x51\xce\x0d\x2b\x17\xd9\x27\x7f\x78\xb3\x12\xf3\x75\xb7\xd3\xb9\xd5\x1c\xc7\x0d\x2e\xad\x13\xaf\xf3\x91\xdd\x4b\x1c\x83\x37\xbb\x3d\xd5\xcc\x93\x47\x24\x70\xa5\x65\xf5\xa0\x6c\x5b\x24\x32\xbc\xd0\xf4\xba\x69\xe0\xb5\x40\xc9\x6b\x0b\x1d\x42\x7c\x1b\xa1\x27\x75\x7e\x63\xb2\x8a\x66\x1b\x28\x66\x82\x8f\x6a\x95\x88\x37\x2d\x3f\x7e\x2b\x71\x0c\x05\x6d\x9b\x79\x37\xa6\xd7\x19\xd1\x08\x50\xeb\x22\x5a\x41\x33\x78\xd5\xf6\x36\xa9\x79\x0d\xa6\x5c\x52\xf0\xbf\xf4\xb3\xe9\x26\x47\x95\x76\x0d\x67\x45\x01\xa5\x25\x78\xf7\x7d\x2d\x0d\x72\x91\x33\x87\xf6\x02\x24\xaa\x7e\x69\x07\xf0\x5f\x38\x07\x1f\xb4\x3f\x94\xec\x7d\x12\x81\x09\x50\xda\xf4\x2d\x4a\x5f\x91\x30\xb4\x8f\x32\x9b\xc5\xd5\x20\xe8\x74\x0a\x6d\x40\xf8\xd2\x60\x6a\x8e\x64\x36\xd0\x3b\xa5\xfd\x22\xbe\xd6\xca\x03\x4f\xf4\xc8\xd0\x4f\x74\x3c\xc1\x45\xdf\x41\xff\xe4\x6e\x04\x27\x45\x28\x5b\x7f\x24\x36\xe2\x19\xe3\xd4\x06\xfa\x3e\xd6\x22\x9b\x3e\x3c\x54\x8e\x8e\x7c\x40\xab\x90\x3e\xd7\x58\xb0\x4a\xba\x74\x06\xa2\x80\x15\x1d\xda\x21\x28\x68\x5d\xa4\x5a\xf7\xa6\x60\xb3\xb9\x88\xf2\xff\x9a\x80\x12\x32\x85\x12\x80\x09\xee\x64\x33\x5f\x68\xac\x2c\x51\xf1\xfe\x3e\x67\x74\x3c\xa3\xda\x19\x51\x1c\xcb\x87\x3a\xd5\x86\xde\x9b\x44\x7c\x2e\x4d\x8a\x56\x92\x74\x3a\x9b\x06\xe8\x75\x42\x47\xa3\xb7\xd5\x03\x1a\x91\xd7\xb9\xfd\x1c\x52\x8c\xf3\x9f\x00\x6b\x17\xad\x4b\xce\x8f\xa0\x75\xc9\xf9\xb3\x68\xfd\x0c\x5c\x87\xf1\xfa\x69\xc0\x12\x62\x0d\xc8\xb6\x05\xdd\x5e\x05\x38\xdf\x95\x4e\x68\xc5\x64\x23\xe7\xf6\x01\xcc\x25\x32\x73\x10\xc2\x83\x19\x76\x45\xe2\x47\x50\xf3\xbc\xbf\x2b\xcb\x7e\x25\xa1\xf6\xcb\xf7\x48\x29\x63\x28\xe5\x1b\x3e\xc7\x58\xc9\x09\x39\xcc\x3e\x29\xf1\x58\xa5\xf6\x7a\x0c\x36\xf4\xb9\x87\xd9\xcc\x99\x2a\x77\x7b\xb8\xd1\x5e\xbf\x0b\xb7\x00\x7c\x72\xe4\xc0\x09\xf4\xc8\x52\x8f\xec\xa6\xcc\x5e\xaf\xc1\xe1\x43\x29\xa9\xa3\xed\x4c\x0b\x1c\x0b\xf4\xc2\x59\x92\xdd\xeb\xe0\x01\x78\xef\xfa\xe1\x33\x69\xb0\x46\x40\x7b\x0d\x52\x7f\xf3\x3b\x85\x6b\x30\x06\xa7\x34\xc7\x83\x2d\xd9\xe0\x83\x5e\x1d\x8e\x32\xf4\x68\xaf\xd9\x68\xd3\xcf\x46\xdd\xa3\x8b\xd2\xf6\xc0\x99\x0a\xa1\xf7\x19\x8d\xee\xc5\xb9\xe2\x9f\xc7\x23\xed\xf4\x1c\x1a\x01\x86\x56\xa3\x39\x84\xc3\x2f\xc1\xf0\xe3\x28\xec\x82\xd0\x0c\xf4\x40\x6f\xab\x19\xdb\xf8\x0f\xd4\xc7\xce\x60\xd1\x98\xaa\x26\xf0\x62\x67\x94\xca\xb5\x2a\xc4\xbc\x3d\x71\x04\x3a\x29\x07\xab\x97\xd6\x8a\xb9\x82\x84\xa6\xf3\x4d\xdb\xd3\x7c\x5f\xb4\xb5\xe0\x2c\x67\x91\xb4\x2b\x6c\x6b\x7a\x7f\xf0\x1d\x77\x45\xe1\x47\xb9\x09\xec\x0d\x6e\x04\x38\xcd\x8d\xa3\x96\xb7\xdc\xd0\xd7\x08\xbc\x0b\x83\x0b\xaf\xbe\xbd\x32\x76\x2b\xa5\xee\x02\xae\x1e\x1a\x0f\x5a\xb2\x7f\xd9\x54\x23\x09\xef\x46\xa0\x97\x94\x84\x68\x4c\xd6\x1f\x36\x66\x4d\xf7\x9a\xde\x2a\x37\x7e\x5c\xbd\x20\x21\x9f\x70\xc1\x9b\x17\x3b\xec\x75\xab\x79\xbe\x61\xf7\x28\xfd\x8c\x13\xe2\x12\x05\xe4\x68\x4c\xb2\x25\xec\xec\xff\x6f\x7c\x6b\x35\x4c\x28\xe7\x37\xe9\xa3\x69\xdb\x21\xa5\x90\x3e\x1d\x83\xae\x32\x0a\xea\x27\x42\x84\xc6\xcf\x7f\x0d\x5e\x42\x4d\x09\xd9\xf5\xaf\x92\x34\xfd\x1f\x79\x2e\xd5\xa9\x9e\x0e\x3a\x75\xeb\xf0\x0c\xa2\x5c\x86\x53\xe2\x91\xd4\xee\xb0\x4e\xbc\x74\xe9\x7c\x40\x39\xde\x9e\x51\x28\xe0\x0f\x28\xfd\xb5\x13\xef\x8e\xa9\x5a\xa1\xb1\x71\x76\xc6\x6c\x6a\x23\x21\xb2\x8f\xcc\xf3\x41\xd8\x33\xf7\xee\xa2\xe6\x7c\x1f\xee\x92\xb7\x2f\xdf\xc6\x87\x50\x7b\x87\xf7\xff\x6b\xa8\x6f\xdf\x27\x5f\xbe\x5a\x67\x84\x9a\xb7\x8f\x30\xa8\x05\x23\x0d\x55\xd8\xbe\xa8\xc8\x89\x57\x82\x8b\x14\x11\x7d\xd7\xc1\x98\x39\xba\xf1\x1e\x58\x81\xba\x0e\xef\x0e\x42\xee\x99\xb7\xc7\xfe\x0d\x8e\xe1\x06\xff\xb1\xf7\x43\x14\x6e\xc3\x18\xb7\xf8\xde\x5b\xc2\x77\xd4\x94\x02\xbe\xd4\x42\xbd\xd0\x9c\xbf\x1c\xc1\xdd\x76\xd4\x0f\x3d\xbc\x6e\xc5\x27\x82\xfb\xec\xa9\x4d\x85\xdc\x09\xcc\xb3\x21\x5c\x69\x3a\x73\x07\x01\xf4\x53\xc1\x2d\xb8\x05\x73\xc0\x0c\x82\x75\xda\x20\x07\x66\x41\x28\x97\xfe\x3b\x80\x33\xc7\xee\x99\x45\x18\x9e\x35\xb7\x12\x05\x30\xc5\xe3\x2b\x40\xf0\xec\x93\x45\x73\xed\xb3\x9b\x0f\x3c\x61\x6a\x67\xde\x44\x6a\xf5\xcb\xd0\x47\xc6\x13\x32\x9d\x6b\xb5\xca\x2e\x9d\x16\xfd\xe5\x20\x8d\x6b\xbb\x5d\x82\xfe\x34\x8a\x2a\x22\xf1\x79\xa7\xee\x0e\x0d\x41\x1d\x5f\x26\x59\x38\xe8\x88\x5c\x7d\x3b\xb4\x58\x23\x58\xb6\x2f\x87\xc6\xe7\x9f\x01\x00\x00\xff\xff\x90\xb4\xcb\xa7\xa6\x11\x00\x00") +var _templateDialectSqlUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x58\x5f\x6f\xdb\x38\x12\x7f\x96\x3f\xc5\xd4\x30\x0a\x3b\x70\x94\x5c\xdf\xce\x85\x0f\x48\x93\xf4\x60\x5c\x9b\xf6\xe2\x76\x1f\x5a\x14\x01\x23\x8e\x6c\xc2\x32\xa9\x90\x54\x36\x5d\xc3\xdf\x7d\x31\xfc\x23\x4b\x91\x9d\x36\xdb\x05\xf6\xa1\x2e\xc5\x99\xe1\x0c\x7f\xf3\x87\x33\xd9\x6c\x4e\x8e\x7a\xe7\xaa\xfc\xae\xc5\x62\x69\xe1\xd5\xe9\xbf\xfe\x7d\x5c\x6a\x34\x28\x2d\xbc\x65\x19\xde\x2a\xb5\x82\x99\xcc\x52\x38\x2b\x0a\x70\x4c\x06\x88\xae\xef\x91\xa7\xbd\x4f\x4b\x61\xc0\xa8\x4a\x67\x08\x99\xe2\x08\xc2\x40\x21\x32\x94\x06\x39\x54\x92\xa3\x06\xbb\x44\x38\x2b\x59\xb6\x44\x78\x95\x9e\x46\x2a\xe4\xaa\x92\xbc\x27\xa4\xa3\xbf\x9b\x9d\x5f\x5e\xcd\x2f\x21\x17\x05\x42\xd8\xd3\x4a\x59\xe0\x42\x63\x66\x95\xfe\x0e\x2a\x07\xdb\x50\x66\x35\x62\xda\x3b\x3a\xd9\x6e\x7b\xbd\xcd\x06\x38\xe6\x42\x22\xf4\xb9\x60\x05\x66\xf6\xc4\xdc\x15\x27\x55\xc9\x99\xc5\x3e\x6c\xb7\xc4\x31\x28\x57\x0b\x98\x4c\x61\x90\xce\x33\x55\x62\xfa\x91\x65\x2b\xb6\xc0\x48\xbd\xad\x44\x41\xd6\x4e\xa6\x50\x32\x93\xb1\xa2\x66\x7c\x13\x28\x81\x51\x63\x86\xe2\xde\x73\xd6\xeb\x5a\x3c\x30\xad\x2b\xcb\xac\x50\xd2\x1d\xa7\x85\xb4\x0d\xb9\x7e\x1a\xa9\xb5\x69\x4a\x22\x71\x2e\x99\x99\x57\x79\x2e\x1e\x76\xe7\xf5\x3f\xc8\x78\x83\x63\x18\xfc\x81\x5a\x11\xe3\x29\x6c\xb7\x9b\x0d\x88\xdc\x8b\xba\x0f\x4f\x9c\x42\x5f\x8a\xa2\xef\xb7\x50\xf2\x5a\x54\xa3\x25\xc9\xbe\xec\xef\x93\x25\x2a\x41\x73\x1d\x8d\x6c\xca\xf7\xf2\x4a\x66\x30\x6c\x5d\x7e\xbb\x85\xa3\x26\x6c\xdb\xed\x08\xcc\x5d\x31\x67\xf7\x38\xcc\xec\x03\x64\x4a\x5a\x7c\xb0\xe9\xb9\xff\x7f\x14\xc5\x2d\x49\xb6\xd4\xbb\x63\xd2\x2b\xb6\x0e\xb6\x60\x61\x68\x25\xa4\xad\x2d\x18\x03\x6a\x4d\xff\x94\x1e\xc1\xa6\x97\xdc\x98\x12\x33\xba\xcd\x4b\x73\x57\x2c\x34\x2b\x97\xe9\x67\xe7\xeb\x79\x89\xd9\xa6\x97\x24\x57\x8a\xe3\xa4\x41\xa5\xef\x48\x4b\x3e\xb1\xdb\x02\x27\xe0\xd4\xee\x82\x20\x75\xdb\x63\x62\x38\x57\x45\xb5\x96\xa6\xcb\x12\x08\x8e\x69\x76\xd1\x54\xf0\x56\x60\xc1\x6b\x0d\xc9\xa7\xef\x25\x4e\x20\xa7\xcd\xd4\x1d\x32\xbb\x48\x69\x8f\xe0\x30\x36\xdc\xd5\x1d\x13\x94\x75\x75\x45\x31\x27\xc1\xa4\x8d\x02\xee\x97\x7e\xb6\xbd\x84\x1c\xbb\x03\xb2\x97\x24\x82\x8f\x41\xad\x08\x99\x56\x10\x36\x8e\x7b\x1f\xf6\xfe\xeb\x3c\x31\x1c\x91\x50\x0e\x2f\xd4\x0a\x9c\xe5\x1a\x6d\xa5\x25\xd4\xe1\x44\xd8\xe7\x6b\x9b\x5e\x12\xf6\xf9\xb0\xbf\x16\xc6\x08\xb9\x80\xa6\xcf\xd2\xd9\x05\xe4\x4a\x43\x48\x37\x3a\x92\x6c\x71\x4e\x72\xc8\x93\xde\xdf\x58\x51\x21\x4c\x41\x70\x6f\x76\xf0\xb2\x57\x5f\x9a\x68\x72\x23\xbe\xd2\x52\x23\x17\x19\xb3\x68\x5e\x43\x81\x72\x58\x9a\x11\xfc\x07\x4e\xbd\xa1\xfe\xf4\x8f\x91\x05\xa6\x40\x41\x3a\x34\x58\xb8\x72\x01\x47\xe6\xae\x48\xe7\xe1\x6b\xe4\x65\x12\xb2\x52\xb8\xbc\x65\x72\x81\xa4\xd6\xef\x27\xa5\xf9\x2a\xbe\xd5\xc2\x23\xb7\xb9\xed\x85\x9f\x00\x74\x48\x06\xb7\xf6\xf2\x83\x9b\x31\x0c\x72\x5f\x53\x5c\x00\x18\x7f\xa3\xe8\x17\xa5\x61\x28\x95\x85\x41\x9e\xce\xd6\xe4\x8c\xdb\x02\x47\xf4\xe5\x83\xf5\x02\x73\x56\x15\x36\xc8\x10\x0e\xf7\x04\xd2\x53\x1e\xcc\x3b\xfe\x7b\x0d\xd1\x75\x11\x13\x6f\x49\x3a\x77\x19\xcd\xca\x12\x25\x1f\x3e\xa6\x8c\x0f\x87\x6e\x37\x78\xf3\x43\xa1\x9b\x24\xce\xab\x93\x60\x77\xd8\x7b\x2a\xa0\xf3\x4e\x38\x27\xc9\xb6\x01\x77\x1d\xd1\x41\xe7\x55\xb5\x46\x2d\xb2\x08\xd1\x0f\x31\x3a\xe3\x1c\xb9\x57\x34\xb7\xba\xca\xac\xbb\x5c\x07\xa8\x36\x52\x67\x9c\x1f\x40\xea\x8c\xf3\x27\x91\x7a\x0e\x54\x7b\xb1\x7a\x36\x58\x11\xad\x06\x5c\x31\x2e\xf7\x7d\x79\x28\x3f\x94\x84\x0f\x2b\x1a\x91\xb6\x3f\xb8\xda\x98\x9d\x17\xc8\x34\xf2\xe1\x68\x6f\x7c\x39\xea\x01\xdc\x1c\xed\xef\x8a\xb1\x5f\x89\xa7\xc7\x79\x7b\x20\x87\xd1\xe7\xf0\x25\x5f\x60\x48\xe1\x08\x1e\xa6\x9f\xa5\xb8\xab\x42\xa9\x3a\x84\x1c\xfe\x00\x39\x3a\xed\x77\x61\x97\x80\x0f\x96\x4c\x18\x40\x9f\x74\xf5\x49\x73\x0c\xed\xcd\x06\x2c\xae\xcb\x82\x8a\x59\xab\x8b\xe1\x98\xa3\x63\x4e\x23\x6f\xdb\xcf\xc1\x2d\xce\xf8\xfd\x5e\x69\x90\xc6\x40\x67\x8d\x62\x69\x6b\x57\x62\xba\x9e\x54\x1c\xcd\xbe\xd4\xba\xc6\xb5\xba\xf7\xc9\xf5\xf8\xba\xb3\x0b\x43\xf9\x45\x35\xda\x89\x37\xca\xf4\x93\x57\xef\xd3\xe3\x60\xfa\x60\x75\x85\xd0\xff\x82\x5a\xf5\xeb\x67\xe7\x9f\x06\x25\x9e\xf4\x14\x24\xcf\xc4\xe2\x97\xa0\xf8\x79\x24\xda\x40\x34\x2f\xbb\xa7\xd0\xd5\x84\x1d\x06\x7b\x52\xa5\xd5\x63\x34\xfa\xb8\x29\xbc\x6c\x35\x6f\x99\x92\xb9\x58\x4c\x3a\x2f\xb9\xdf\xdf\x35\x05\x67\xc6\x88\x85\x84\xf8\xe4\xd3\x59\x29\x73\x7b\xae\x48\x9a\x9a\x71\x9e\xb1\xb0\xd5\x66\x36\xf5\x3e\x75\x30\x4f\x9a\x2b\x72\xd7\x3c\x4e\xe1\x51\xab\x48\x80\x53\xa7\x3a\xee\x58\xcb\x35\xad\xc6\xe0\x4c\x18\xbd\x76\xe2\x2f\xa6\x20\x45\x41\x7e\xec\x34\x2f\x3b\xb3\xc6\x87\x35\x99\xbf\xac\xaa\x11\x88\x37\xf1\xd9\x43\xad\xd3\xe1\x51\xa3\xbb\xb5\x6f\x69\x98\x72\x4d\x5a\xe3\xa1\xf3\xd6\xbc\x6c\x91\x37\x9d\x3a\xfa\x8e\xdd\x62\xe1\xfa\x1c\x7f\x2f\x91\x43\x86\x5a\x47\x5d\xc2\xcc\xff\xff\xce\x55\x59\xcd\x84\xb4\xee\x90\x21\xea\xae\x1e\x12\x0a\xad\xdf\xbe\x2e\xd2\x51\xb7\xbd\x26\x2d\xa2\x26\x45\xd1\x73\x73\x50\x9c\x37\x0e\xcc\x73\x75\xa8\x47\x47\xc7\xc2\xed\xe7\x34\x8a\x65\x38\x26\x1a\x71\xb5\xc7\x03\xa2\xc5\xf7\xe7\x1a\x8b\xc9\xce\x47\x3e\x89\xaf\xb1\x70\x2f\x50\x78\x46\x66\xf2\x1e\xb5\x09\x43\x02\xa6\x33\x13\x36\x02\xf9\xc0\x04\xe1\x99\x1d\xf1\xd1\xb3\xd4\x9c\x28\xfc\xb3\xf2\xfe\xd5\xfb\x30\x7a\x75\x4f\xf8\xf8\xbf\x86\xf8\x6e\x22\xfa\xfa\xcd\x58\x2d\xe4\xa2\xeb\x42\x2f\xe6\x95\x34\x44\x61\x37\xc3\x91\x11\x6f\x04\x17\xf1\x46\xb4\xae\x2f\xa3\x17\x68\x27\x8f\xc0\xf2\xbb\x1b\x3f\xe9\x10\x72\xcf\x98\x76\xd0\x3f\xe6\x3f\x37\xf3\x04\xe6\x2e\x8c\xe1\x88\x1f\xcd\x3f\xae\xa2\xc6\x10\x70\xa9\xe6\xf3\x85\x7a\xfd\x9b\x31\xac\x76\xed\xbe\xaf\xe3\x75\x29\x1e\x08\xee\xa2\xa7\x56\xe5\x63\xc7\x13\x4f\x8e\xe0\x5c\x91\xcf\x2d\x78\xd0\x8f\x05\x37\x60\x97\xcc\x02\xd3\x08\xc6\x2a\x8d\x1c\x98\x01\x1a\xed\xc3\xdf\x2b\x38\xb3\xec\x96\x19\x84\xa3\x93\xe6\x51\x22\x07\x26\x79\x98\x04\x04\x4f\x3f\x1b\xd4\x17\x2e\xba\xf9\xc8\x6d\xcc\xcc\xdc\xa9\x88\xa5\x7e\xe5\xeb\xc8\x64\x4a\xaa\x33\x25\xef\xd3\x33\xab\xc4\x70\x35\x8a\xcd\x5b\xbb\x4a\x24\xed\xb1\x2d\x20\xf1\xa5\x95\x77\xfb\xfa\xa1\xc4\xa5\x49\xea\x1d\x1d\x90\xab\x5f\x87\x0e\x69\x0c\xab\xee\xe3\xd0\x58\xfe\x19\x00\x00\xff\xff\x2a\xc3\x27\x2a\x47\x12\x00\x00") func templateDialectSqlUpdateTmplBytes() ([]byte, error) { return bindataRead( @@ -815,7 +839,7 @@ func templateDialectSqlUpdateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/dialect/sql/update.tmpl", size: 4518, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/dialect/sql/update.tmpl", size: 4679, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -860,7 +884,27 @@ func templateHeaderTmpl() (*asset, error) { return a, nil } -var _templateImportTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x4f\x4b\xe4\x4e\x10\x3d\x4f\x3e\x45\x11\xe6\xa0\xf2\xb3\xe3\xcf\xdb\x0a\x1e\x44\x14\x84\x65\x11\xf4\xbe\xf4\x74\x57\x92\xc2\xa4\x2b\x5b\x5d\xe3\x2a\x21\xdf\x7d\xe9\x4e\xc6\x99\x61\x58\xf6\x94\xd7\xfd\x5e\xfd\x49\xf5\xab\x71\xac\x2e\x8a\x7b\x1e\x3e\x85\x9a\x56\xe1\xfa\xea\xff\x6f\x97\x83\x60\xc4\xa0\xf0\x68\x1d\x6e\x98\xdf\xe0\x29\x38\x03\x77\x5d\x07\x59\x14\x21\xf1\xf2\x8e\xde\x14\xaf\x2d\x45\x88\xbc\x15\x87\xe0\xd8\x23\x50\x84\x8e\x1c\x86\x88\x1e\xb6\xc1\xa3\x80\xb6\x08\x77\x83\x75\x2d\xc2\xb5\xb9\xda\xb1\x50\xf3\x36\xf8\x82\x42\xe6\xbf\x3f\xdd\x3f\xfc\x78\x79\x80\x9a\x3a\x84\xe5\x4e\x98\x15\x3c\x09\x3a\x65\xf9\x04\xae\x41\x0f\x8a\xa9\x20\x9a\xe2\xa2\x9a\xa6\xa2\x18\x47\xf0\x58\x53\x40\x28\xa9\x1f\x58\xb4\x84\x69\x2a\x66\x08\x67\xc5\xaa\xac\x7b\x2d\x8b\x55\xe9\x38\x28\x7e\x64\x88\x22\x2c\x31\xa1\xde\x6a\x9b\xbe\x51\xc5\x71\x78\x5f\x20\x85\x26\xb3\x4a\x3d\x96\xc5\x6a\x1c\x2f\xa1\xba\x00\x6a\x02\x0b\x42\x83\x01\x45\x29\x34\xc0\x01\x1a\xb1\x43\x0b\x71\x40\x47\x35\xd5\x0e\x14\xfb\xa1\xb3\x8a\x11\x72\x73\x39\x94\x6a\x08\xac\x70\x86\xbf\x60\x6d\xee\x39\xd4\xd4\x98\x67\xeb\xde\x6c\x83\xb0\xde\xa1\xf3\xd4\xf4\x6a\x55\x8e\xe3\xa9\x68\x9a\xaa\x41\xd0\x93\xb3\x9a\xda\xf9\xab\x28\x5f\xef\xcf\x49\x9a\xea\xff\x26\x6d\xf7\xfa\x17\xd7\x62\x6f\x61\x2e\x97\x53\x99\x03\x2d\x06\x3f\x33\xe9\x20\x36\xa4\x16\x7f\xfe\x07\xeb\x1a\x6e\x6e\x61\x6d\x1e\x09\x3b\x1f\x97\xd8\x7d\xee\xda\xbc\x7e\x0e\x68\x9e\xdf\x9a\x67\xab\xed\x42\x1f\xe5\x3e\x4d\xbe\x3b\x1c\xe2\xb2\x21\x6d\xb7\x1b\xe3\xb8\xaf\xea\xc5\x7e\x14\xdc\x76\x63\x95\xa5\xc2\x90\x1f\xef\x5f\x9a\xca\x93\xed\xd0\xcd\x5a\xee\x6c\x68\x0c\x4b\x53\x7d\x54\x1f\x5f\xcf\x7e\x30\x95\x17\x65\x99\xc7\x75\xfa\xd3\x8b\x87\x6e\x6e\xc1\x3c\x65\x18\x0f\xa6\xb6\x63\x4f\x67\x77\x8c\xbf\x2c\xb1\xb3\x67\xac\xac\xf7\xa4\xc4\xc1\x76\x25\xac\x93\xec\x3c\x99\x78\x09\x29\xd2\x4e\xc2\xdd\x3e\x4c\x5b\xab\xe0\x6c\x80\x0d\x02\xbf\xa3\x08\x79\xf4\x69\x4d\x58\xf2\x82\x31\x58\xef\x61\x9f\x13\x96\x32\x89\x19\x66\x33\x44\x93\xdd\x78\xb2\x29\xc7\xad\x4c\xd3\x38\x62\xf0\xd3\x54\xfc\x09\x00\x00\xff\xff\xa5\x33\x84\x1e\x17\x04\x00\x00") +var _templateHookTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x54\xc1\x8e\xe4\x34\x10\x3d\x27\x5f\xf1\x88\x7a\xa5\x64\xd4\x38\xcb\xde\x40\xe2\xb0\x1a\x66\xc5\x48\xcb\x34\x82\x81\x0b\xe2\x60\x92\x4a\xc7\x74\x62\x5b\xb6\x33\xdb\xad\x90\x7f\x47\xe5\xa4\xd3\x81\xe1\x82\x38\x71\xe9\x4e\xaa\x5e\xd5\x2b\xbf\x57\xce\x38\x96\x77\xe9\xbd\xb1\x17\xa7\x8e\x6d\xc0\xbb\xb7\x5f\x7c\xf9\xb9\x75\xe4\x49\x07\x7c\x90\x15\xfd\x66\xcc\x09\x8f\xba\x12\x78\xdf\x75\x88\x20\x0f\xce\xbb\x17\xaa\x45\xfa\xdc\x2a\x0f\x6f\x06\x57\x11\x2a\x53\x13\x94\x47\xa7\x2a\xd2\x9e\x6a\x0c\xba\x26\x87\xd0\x12\xde\x5b\x59\xb5\x84\x77\xe2\xed\x35\x8b\xc6\x0c\xba\x4e\x95\x8e\xf9\x8f\x8f\xf7\x0f\x4f\x3f\x3e\xa0\x51\x1d\x61\x89\x39\x63\x02\x6a\xe5\xa8\x0a\xc6\x5d\x60\x1a\x84\x0d\x59\x70\x44\x22\xbd\x2b\xa7\x29\x4d\xc7\x11\x35\x35\x4a\x13\xb2\xd6\x98\x53\x86\x25\xf8\x49\x85\x16\x74\x0e\xa4\x6b\xec\x90\x7d\x2f\xab\x93\x3c\x52\xb6\x41\x25\xe3\x88\x40\xbd\xed\x64\xe0\x62\x92\x35\xb9\x0c\x82\x53\xe3\x08\xae\xe3\x56\xaa\xb7\xc6\x05\x64\xe3\x88\x9d\xb8\x37\xba\x51\x47\xb1\x34\xc3\x34\x65\x91\xcb\x49\x7d\x24\xec\x34\xbe\xfa\x1a\x3b\xf1\x64\x6a\xf2\x57\x82\x9d\x96\x3d\x71\xdc\x3a\xa5\x03\x76\x5a\x3c\x71\x20\xfb\x30\xe8\x6a\x9d\x62\x17\x2e\x76\x03\xca\xee\x48\x07\x91\x31\xf8\xbb\x21\xc8\xa0\x8c\x8e\x45\x3c\x4e\x52\x96\x78\x6e\x09\x6b\xeb\x69\x42\xac\x56\x1e\x52\x43\xd6\xd2\x06\xd6\xdd\x40\x76\x9d\xf9\x14\xc5\x1c\x3c\xb1\x82\xc6\xd5\x4a\x4b\x77\x89\x3d\x9a\x41\x57\xdc\x18\xd2\xcf\xbd\xc4\x42\x81\x9e\x29\x8d\x13\x69\x12\xfb\x6e\x89\xb8\x28\xaf\x8c\x0e\x74\x0e\xac\x05\xff\xef\xb1\x1e\x60\x9a\x0a\xe4\x3c\xfa\xcf\xb2\x1b\x68\x0f\x72\xce\xb8\x62\x9e\x39\x1e\x84\x50\xc9\xae\xf3\x68\xf2\x2a\x9c\xf7\xe8\x0b\x91\x26\xdc\x13\x79\xb3\xe5\x29\x16\x34\xa3\xf0\x8a\xae\x07\x53\x5c\x85\xf9\x27\x46\x8c\x69\x92\xf4\x2f\x7b\x98\x13\x8b\xda\x8b\x7c\x3b\x62\x9a\x24\xaa\xc1\x67\xe6\x14\x61\x89\xa3\x30\x38\x0d\xad\xba\x3d\x9a\x3e\x88\x07\x6e\xd1\xe4\xd9\xa0\xe9\x6c\xa9\x0a\x54\xcf\x8a\xb0\x56\xb1\xc5\x9b\x67\x81\x39\xb5\x3d\x79\xc6\xc7\x49\x93\x64\x4a\xd7\x96\xd7\x53\xbe\x14\x69\xf2\x97\x95\x2a\x4b\x1c\x34\xe8\x4c\xd5\x10\xc8\x47\x8b\x8e\xea\x85\x34\x78\x35\x61\x74\xb7\x2c\xfc\x35\x6c\x2c\xb9\x38\x80\x48\xcb\x32\x2d\xcb\x84\x71\xe2\xa0\xf3\x8f\xe6\xb8\x8f\x6a\x7c\x43\x1d\x05\xfa\x83\x1f\xef\x1d\xc9\x40\x05\x23\xa3\xb4\x07\x9d\xb7\xa7\x08\xfa\xd6\x98\xd3\x1e\xc6\xc6\x97\x83\x2d\xd6\x20\x0b\x71\x9d\x99\x1d\xd6\x74\x0e\x37\x91\x59\xd0\xcd\x4b\x54\x6d\x41\xaf\x61\xe2\x75\xce\xe7\xf5\xf8\x0f\x9e\xb1\x31\xbd\x38\xd8\xbc\x10\x8f\x3e\x37\x76\x89\x5e\xe9\xda\x53\x1c\xad\x10\xb7\xf5\x58\x54\x8f\xb2\xaf\x56\x32\xf5\x2b\xc8\x14\x5d\x98\xd5\xff\x81\x7e\x67\xfb\x66\xbc\x87\x9c\x85\x0f\xad\xe4\x18\xa7\x3c\xdf\x9e\x9b\xee\x7e\xce\xf5\x32\x54\x2d\x8c\xbd\xda\x30\xaf\xee\x73\x01\x16\xd1\xe7\x05\x7e\xf9\x75\x23\x69\x59\xae\x13\xdd\xe2\x73\x38\x99\x07\xc8\xff\x66\xdd\x4f\xb6\x66\xeb\xf6\x11\x33\xf1\xef\xb4\xda\xb8\x54\xfc\x8f\xdd\x7b\x75\xc3\xde\xf8\x9b\xc2\xfc\xf9\xd2\x26\xcc\x1f\x2d\xaa\xf9\x36\xc5\x4e\xff\xd2\xdc\xf5\x92\xfd\x19\x00\x00\xff\xff\x96\xc4\xeb\x5e\xda\x06\x00\x00") + +func templateHookTmplBytes() ([]byte, error) { + return bindataRead( + _templateHookTmpl, + "template/hook.tmpl", + ) +} + +func templateHookTmpl() (*asset, error) { + bytes, err := templateHookTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "template/hook.tmpl", size: 1754, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templateImportTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\xd1\x4a\xdd\x40\x10\x7d\xbe\xf9\x8a\x43\xb8\x0f\x2a\x75\x63\x7d\xab\xe0\x83\x88\x82\x50\x8a\xa0\xef\x65\xef\xee\x24\x19\x4c\x76\xd2\xdd\xb9\x56\x09\xf9\xf7\x92\x4d\xae\x5a\xa4\xf4\x29\x27\x39\x67\x76\xe6\xec\x9c\x8c\x63\x75\x52\x5c\xcb\xf0\x1a\xb9\x69\x15\xe7\x67\x5f\xbf\x9d\x0e\x91\x12\x05\xc5\xad\x75\xb4\x13\x79\xc2\x5d\x70\x06\x57\x5d\x87\x2c\x4a\x98\xf9\xf8\x4c\xde\x14\x8f\x2d\x27\x24\xd9\x47\x47\x70\xe2\x09\x9c\xd0\xb1\xa3\x90\xc8\x63\x1f\x3c\x45\x68\x4b\xb8\x1a\xac\x6b\x09\xe7\xe6\xec\xc0\xa2\x96\x7d\xf0\x05\x87\xcc\x7f\xbf\xbb\xbe\xf9\xf1\x70\x83\x9a\x3b\xc2\xfa\x2d\x8a\x28\x3c\x47\x72\x2a\xf1\x15\x52\x43\x3f\x34\xd3\x48\x64\x8a\x93\x6a\x9a\x8a\x62\x1c\xe1\xa9\xe6\x40\x28\xb9\x1f\x24\x6a\x89\x69\x2a\x16\x88\xa3\x62\x53\xd6\xbd\x96\xc5\xa6\x74\x12\x94\x5e\x32\xa4\x18\x25\xa6\x19\xf5\x56\xdb\xf9\x99\x34\x3a\x09\xcf\x2b\xe4\xd0\x64\x56\xb9\xa7\xb2\xd8\x8c\xe3\x29\xaa\x13\x70\x13\x24\x12\x1a\x0a\x14\x95\x43\x03\x09\x68\xa2\x1d\x5a\xa4\x81\x1c\xd7\x5c\x3b\x28\xf5\x43\x67\x95\x12\xf2\x70\xb9\x94\x6b\x04\x51\x1c\xd1\x2f\x6c\xcd\xb5\x84\x9a\x1b\x73\x6f\xdd\x93\x6d\x08\xdb\x03\x3a\x9e\x87\xde\x6c\xca\x71\xfc\x2c\x9a\xa6\x6a\x88\xe4\xd9\x59\x9d\xc7\xc9\x87\x46\x1b\xe6\xf2\x9f\x5f\xb0\xad\x71\x71\x89\xad\xb9\x65\xea\x7c\x5a\x8e\xc9\x92\xdf\xac\x2d\xb6\xb5\x79\x7c\x1d\xc8\xdc\x3f\x35\xf7\x56\xdb\x95\xce\x7d\x0c\xa6\xa9\x3c\x88\x29\xf8\x85\xfb\xf8\xf2\x11\x97\x0d\x6b\xbb\xdf\x19\x27\x7d\x55\xaf\xd1\xe0\xe0\xf6\x3b\xab\x12\x2b\x0a\xf9\x62\xff\xa7\xa9\x3c\xdb\x8e\xdc\xa2\x95\xce\x86\xc6\x48\x6c\xaa\x97\xea\xe5\x6d\x25\xef\x93\x9b\x07\x95\xb8\xf8\xff\x6c\x7a\xdd\xef\xc5\x25\xcc\x5d\x86\x07\xe7\xf9\x06\x57\x76\xf1\xf7\x2f\x47\xe3\xf8\xb6\xae\x43\x74\x52\x65\xbd\x67\x65\x09\xb6\x2b\xb1\x9d\x65\xc7\x73\xc0\xd6\x92\x62\xfe\x5f\x70\xf5\x5e\xa6\xad\x55\x38\x1b\xb0\x23\xc8\x33\xc5\xc8\x9e\xfc\x1c\x61\x89\x39\xfc\x02\xeb\x3d\xde\xcf\xc4\xda\x66\x66\x86\x65\xbb\xc9\xe4\xa4\x7c\x4a\xf1\xdf\xa3\x4c\xd3\x38\x52\xf0\xd3\x54\xfc\x09\x00\x00\xff\xff\x73\x8f\xdd\xf9\xb3\x03\x00\x00") func templateImportTmplBytes() ([]byte, error) { return bindataRead( @@ -875,12 +919,12 @@ func templateImportTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/import.tmpl", size: 1047, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/import.tmpl", size: 947, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateMetaTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\xdf\x6f\xe3\xb8\x11\x7e\x96\xfe\x8a\xa9\xa0\x05\xec\x20\x2b\xe7\xee\xad\x29\xfc\xb0\xdd\x64\x51\xa3\xd7\xed\x01\x97\xbd\x3e\x04\xc1\x82\x96\x46\x31\xef\x64\xca\x47\xd2\xde\x04\x82\xfe\xf7\x62\x86\xa4\x44\x39\xf6\xe6\x76\x8b\xe6\x25\x96\x48\xce\x8f\x6f\x3e\x7e\x43\xaa\xeb\x16\x17\xe9\xfb\x76\xf7\xac\xe5\xe3\xc6\xc2\x8f\x57\x3f\xfc\xf5\xed\x4e\xa3\x41\x65\xe1\x83\x28\x71\xdd\xb6\xbf\xc3\x4a\x95\x05\xbc\x6b\x1a\xe0\x49\x06\x68\x5c\x1f\xb0\x2a\xd2\xbb\x8d\x34\x60\xda\xbd\x2e\x11\xca\xb6\x42\x90\x06\x1a\x59\xa2\x32\x58\xc1\x5e\x55\xa8\xc1\x6e\x10\xde\xed\x44\xb9\x41\xf8\xb1\xb8\x0a\xa3\x50\xb7\x7b\x55\xa5\x52\xf1\xf8\x4f\xab\xf7\xb7\x1f\x7f\xb9\x85\x5a\x36\x08\xfe\x9d\x6e\x5b\x0b\x95\xd4\x58\xda\x56\x3f\x43\x5b\x83\x8d\x9c\x59\x8d\x58\xa4\x17\x8b\xbe\x4f\xd3\xae\x83\x0a\x6b\xa9\x10\xb2\x2d\x5a\x91\x81\x7b\xf9\x16\xbe\x48\xbb\x01\x7c\xb2\xa8\x2a\xc8\x21\xfb\x59\x94\xbf\x8b\x47\xcc\x20\x2f\xfc\x4f\x78\xdb\xf7\x69\xd2\x75\x60\x71\xbb\x6b\x84\x45\xc8\x36\x28\x2a\xd4\x19\x14\x64\xa5\xeb\x80\xd6\x7a\x27\xe3\x24\xb9\xdd\xb5\xda\x66\x90\xf3\x50\xd9\x2a\x63\x61\x96\x26\x8b\x05\xfc\x24\xd6\xd8\xc0\xa6\x6d\x2a\xc3\x59\x18\xab\xa5\x7a\x84\x86\x5f\x57\xa8\x5a\x4b\x8f\x34\xd2\x75\xd0\xb4\x5f\x50\x43\x5e\x7c\x14\x5b\x84\xbe\x07\xfb\xbc\x1b\xd2\xaf\x84\x15\x6b\x61\xb0\x48\x13\x67\x73\x09\x59\xd7\x41\x5e\xb8\xa7\xbe\xcf\xd8\x1f\xbf\x5a\xdd\x14\xef\x29\x06\xa1\x2c\x99\x79\xe1\x7d\xe2\x57\x56\x50\x4b\x6c\xaa\x13\x8e\x4e\x19\x0b\x6e\x57\x37\xc5\x2f\xb6\xd5\xe2\x11\xff\x89\xcf\xce\x7d\xd7\x81\x16\xea\x11\x21\xff\x7c\x09\x79\x0d\xd7\x4b\xc8\x8b\x0f\x64\xdb\x10\xb0\xb4\xcc\x79\xa2\x81\x7a\xb4\xca\xa0\x87\xe0\xdd\x8c\x57\xa3\x1e\xd1\xaa\x07\xb8\x0e\xa8\x2d\x3e\xc1\x4e\xb7\x3b\xd4\xf6\xf9\x44\x42\xc9\xc4\x83\x4f\xa5\x3e\x95\x08\x95\x39\x90\x21\xb7\xdb\x5d\x43\x41\xef\xb4\x54\xb6\x86\xac\x92\xa2\xc1\xd2\x2e\xde\x98\x05\x11\x6c\x51\xfa\x4c\x0c\x51\xc9\x1b\x03\xbf\xf8\x69\x60\x89\x33\xc3\x14\x99\x33\x7f\xdc\x8b\xf3\x66\x0f\x42\x4b\xb1\x6e\xf0\xd8\x6c\xd7\x81\xac\x61\x23\xcc\xdd\xd4\xf4\xd7\x3c\x4e\x99\x2b\x6b\x68\x89\x68\xff\x10\xe6\x06\x6b\xb1\x6f\xac\x7b\xf8\x55\x34\xb2\x12\xb6\xd5\x86\x66\x1e\x84\x26\x16\x0f\x3b\x27\x2f\xfe\x25\x9f\xb0\x5a\xa9\xff\x48\xbb\xf1\xeb\xfe\xad\x87\x35\xec\x3f\xd9\xca\x27\xa9\x60\x49\x05\x22\xd0\x29\xf2\x72\x83\x5b\x01\x7d\x5f\x30\x71\x7c\xb5\xba\x9e\xac\x49\x35\x9b\x87\x45\x9e\x29\x4b\xb8\x2f\x8a\xe2\xe1\xfe\x01\x95\x75\xec\xe9\xd2\x24\xe1\x28\x3c\xbb\xe4\x25\xe4\x9f\xa9\x1e\x4f\xfe\x45\xf1\x71\xbf\x65\x63\x2e\x04\x6f\xef\x9e\xdc\x49\xe8\xfb\x07\x4f\xc2\xd9\xfc\x32\x58\xf2\x58\x24\x49\x9f\x4e\x9e\xeb\x10\xc3\x9f\x08\x3f\x18\x8d\x89\x2f\x4f\x11\x3f\x75\x3e\xf3\x0a\x4d\x39\xd0\x08\x32\x7a\xcc\x1c\xfd\xf4\xbe\xb4\x3c\x3f\x9a\xbe\xb8\x00\x54\xfb\x2d\x49\x19\x17\xe8\x20\x9a\x3d\x1a\xd8\x08\x55\x35\x58\x81\x42\xc1\x5a\x2a\x35\x54\x58\x36\x42\x0b\x2b\x5b\x65\x0a\x60\x0d\x64\xa6\xbb\x2a\xcf\x04\xa9\x5d\x5d\x84\x42\xcf\x54\x6b\xe9\x79\x65\x6e\xd5\x7e\x3b\x9f\xd3\xef\x4f\xbb\x4a\x58\x1c\xa8\x50\x17\x11\x11\x5c\x44\x1c\x92\xac\x69\xec\xe7\xd6\x48\xf2\x15\xd8\x10\x40\xf7\x1b\x98\xb3\xec\x7b\x52\x7e\xde\xbc\x0e\x3e\x7a\xab\xe5\x8e\x68\x52\xb7\xda\xed\xf4\x61\xe3\x32\xea\x05\x1b\x89\x2d\x2c\x21\xe2\xc5\xbd\x5b\x12\x3b\x97\x6a\xa5\x2a\x7c\xa2\x0a\x1f\x8f\x0e\x03\xc5\xcd\xe0\x98\x99\xe6\xaa\xdd\x18\xfc\x3f\x46\x5d\x9f\x0c\xf8\x95\x90\x02\x21\x63\xed\xf1\x45\xfc\x7a\x01\x61\xac\x4f\x1e\xb8\xe2\x04\xd6\x2f\xe0\x78\x7d\x15\x87\x6c\xdd\xbc\x89\xcc\x4e\x88\x06\xad\x82\x52\x23\x93\x8a\x73\xf7\xa2\x7b\x32\xff\x23\x93\xcb\x18\xd1\x10\x45\x31\x1b\x75\x87\x62\xbf\x93\x5b\x74\xbf\x3e\x7d\x5a\xdd\x40\xdf\xd7\x7b\x55\xce\xe6\x30\x08\x95\x73\x76\x47\x2d\xb0\xef\xe7\xa7\x91\x79\x41\xdd\xb3\x58\x4c\xa6\x7d\x37\x22\x7b\xb6\xf2\xbf\xe1\x31\x89\x24\xa0\x32\x42\xf2\x1d\x40\x38\x71\x3e\xbd\x69\x21\x57\x14\x9e\x03\x61\x94\xea\x68\x9c\x0f\x19\xd7\x4b\x18\xda\x10\xf9\x87\xd9\x1b\x33\x07\xd4\xba\xd5\xd9\xe0\x7d\x8a\x98\xf2\x69\x4b\x03\x82\x10\xf2\x96\x03\x36\xd9\x04\x9c\xcc\xa3\x03\x2b\x4b\x0b\x4a\xd1\x90\x86\xad\x9f\x79\xea\x7a\x2f\x9b\x0a\xb5\x81\x35\xd6\xad\x46\x30\xe2\x80\x01\x47\x59\x03\xfe\x71\x94\xdc\x0f\x21\x92\x24\x8e\x63\x8a\xf2\x38\xfd\xfe\xea\x81\x51\x76\x89\x3a\x04\x19\x42\x12\x81\xd3\x86\xc6\x0a\x84\x45\xc0\x3d\x28\x49\x0e\x63\x14\xd7\xe7\x1c\xba\x99\xb5\xe2\x29\xdc\xcb\xd8\xde\xb4\x8c\x0e\xdb\x60\x36\xee\x6e\xbf\x5d\x42\xae\xe2\xee\x36\xc9\xdd\xc7\x3b\x09\x85\x95\xe6\x37\x96\x96\xd9\x59\x57\xae\xf7\x1d\xab\x4d\xc2\x1d\x90\xfe\x34\xda\xbd\x56\x10\xad\xff\xbb\x2b\xcb\x87\x70\x5c\xfa\x6a\x02\x54\xf6\xcf\x97\x50\x73\xe4\x2e\x70\x42\x20\x0c\x27\x54\x47\xad\x69\xb0\x56\xa7\xed\xcf\xff\xc6\x33\xfe\xb2\x04\x25\x9b\x71\x61\x08\x0c\xb5\x0e\xaf\x02\x04\xe1\xbf\x9f\xa1\x64\x13\x67\xd4\xcf\x86\x4a\xc7\x9b\x25\x3e\xd8\x85\xdf\xf3\xf8\x78\x94\xd2\x15\x28\x5c\x20\xca\xbd\xb1\xed\xd6\x1d\xc4\x29\x45\xee\xc8\xfe\x90\xc0\x8d\xf6\x95\x33\x6f\x9a\x44\xfb\x9b\xe4\x3a\x88\xfc\xe2\x02\xda\xad\xb4\xcc\xff\x9d\xbf\x7c\x30\x01\x6b\x4d\xfe\x36\xc8\x3e\xe3\x6e\x9e\xb3\xef\xeb\x25\x58\x2d\xb7\xe1\xbe\xe2\x0b\x42\x47\x08\x3a\x19\x8f\x17\x99\xf8\x48\x8d\xce\xaf\xcf\xc9\x0c\xd6\xcf\xe8\xd8\x98\x23\x6d\x42\x9e\x18\x5b\x71\xa7\xf1\x34\x8d\x8f\x04\x2f\xe5\x77\x71\x01\x50\x4b\x55\xb1\x7d\x5e\x6a\x37\xc2\x9e\xd3\x56\xca\x33\x3e\x68\x44\x90\x06\xed\x22\xf0\x06\xfa\x7b\xcf\xa4\x0c\x18\xf9\xff\x95\x75\x3a\x10\x9b\xbb\x40\xa4\x7e\x64\x81\x73\xcc\xc7\x39\x2f\xb5\x2c\x8e\x2d\x4a\xdb\xf5\xf9\xc4\x5d\xed\x1c\x5e\x71\x33\x19\xf4\xc7\x5b\x4a\x5f\xee\xb4\xa3\x2e\x3f\x3c\xbc\xac\x93\x3b\xe9\x91\xc7\xe1\x26\xf9\x67\x61\x79\x99\xe7\xc4\xb2\xbf\xf1\xa0\xbb\xe6\x38\xa3\x63\x50\x73\x8a\xc5\xa9\xbf\x89\x97\xcd\xc1\xd1\x6b\x36\x0f\x57\x31\xde\x9d\x7e\xdb\xb9\x57\x33\x33\xe7\xd3\x74\xfa\x6a\xd3\xa1\x61\xa1\x1f\x59\x27\xb0\x44\x79\x70\x97\xb8\x23\x35\x48\xbf\xa9\xcf\x90\xbd\xa1\xc9\x38\xba\x79\x10\xbf\xa9\xe1\x70\xee\x91\xcf\xd9\x68\x7b\x8a\x47\xa4\x7d\xe6\x8b\xb4\xe5\x06\xe2\x99\x5c\x8b\x92\x6e\x0f\xd3\x8b\xc1\x71\xcd\x9c\x34\x28\x1a\x85\x2b\xe8\xfb\xcb\xa3\x96\x1f\xdf\x0b\xf8\xdd\x4e\x98\x52\x34\xae\x7e\xc3\xdc\xeb\xf4\x94\x08\x7a\x0a\x4f\x07\xeb\xad\x2d\x6e\x29\xf4\x7a\xe6\x2e\xf1\xa3\x5a\x5c\x83\x54\x0c\x6e\x84\xde\xb9\x33\xef\x35\xbc\xf9\x23\xbb\x8c\x52\x66\xa1\x1d\x6e\x53\x81\x50\xe7\x3e\x96\xf0\xdd\x56\x54\x15\x1f\x8b\x45\x13\xbe\x9a\x4c\xa6\x2f\x2e\xe0\xdd\xb8\x84\xa5\xa3\x14\x0a\xd6\x08\xed\x01\xb5\x96\x15\xf2\xf7\x8a\x56\xf3\x17\xa5\x16\x44\x55\xc1\x68\xd2\x7d\x7a\x0a\x0c\x61\x05\xf3\x1a\x5b\x0c\xaa\x1d\x7f\x21\x9a\x44\x13\x41\x9b\xfe\x37\x00\x00\xff\xff\x63\xa8\xa9\x16\x0e\x13\x00\x00") +var _templateMetaTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x57\x41\x6f\xdb\xb8\x12\x3e\x5b\xbf\x62\x20\xb8\x80\x1d\x24\x72\xdb\xdb\x0b\x90\x43\x5f\x92\xa2\xc1\x2b\x8a\x02\x49\x7b\x79\x58\x14\xb4\x38\xb2\x89\x52\xa4\x4a\x52\x4e\xb3\x82\xfe\xfb\x82\x43\x4a\xa2\x12\x7b\x77\xdb\x8b\x61\x92\xc3\x6f\x66\x3e\xce\x7c\xa4\xba\x6e\x73\x96\x5d\xeb\xe6\xc9\x88\xdd\xde\xc1\xdb\xd7\x6f\xfe\x73\xd1\x18\xb4\xa8\x1c\xbc\x67\x25\x6e\xb5\xfe\x0e\x77\xaa\x2c\xe0\x9d\x94\x40\x46\x16\xfc\xba\x39\x20\x2f\xb2\x87\xbd\xb0\x60\x75\x6b\x4a\x84\x52\x73\x04\x61\x41\x8a\x12\x95\x45\x0e\xad\xe2\x68\xc0\xed\x11\xde\x35\xac\xdc\x23\xbc\x2d\x5e\x0f\xab\x50\xe9\x56\xf1\x4c\x28\x5a\xff\x78\x77\x7d\xfb\xe9\xfe\x16\x2a\x21\x11\xe2\x9c\xd1\xda\x01\x17\x06\x4b\xa7\xcd\x13\xe8\x0a\x5c\xe2\xcc\x19\xc4\x22\x3b\xdb\xf4\x7d\x96\x75\x1d\x70\xac\x84\x42\xc8\x6b\x74\x2c\x87\x30\x79\x01\x8f\xc2\xed\x01\x7f\x3a\x54\x1c\x96\x90\x7f\x66\xe5\x77\xb6\xc3\x1c\x96\x45\xfc\x0b\x17\x7d\x9f\x2d\xba\x0e\x1c\xd6\x8d\x64\x0e\x21\xdf\x23\xe3\x68\x72\x28\x3c\x4a\xd7\x81\xdf\x1b\x9d\x4c\x46\xa2\x6e\xb4\x71\x39\x2c\x69\xa9\xd4\xca\x3a\x58\x65\x8b\xcd\x06\x3e\xb2\x2d\x4a\xd8\x6b\xc9\x2d\x65\x61\x9d\x11\x6a\x07\x92\xa6\x39\x2a\xed\xfc\xd0\xaf\x74\x1d\x48\xfd\x88\x06\x96\xc5\x27\x56\x23\xf4\x3d\xb8\xa7\x66\x4c\x9f\x33\xc7\xb6\xcc\x62\x91\x2d\x02\xe6\x15\xe4\x5d\x07\xcb\x22\x8c\xfa\x3e\x27\x7f\x34\x75\x77\x53\x5c\xfb\x18\x98\x72\x1e\xe6\x85\xf7\x99\x5f\xc1\xa1\x12\x28\xf9\x11\x47\xc7\xc0\x06\xb7\x77\x37\xc5\xbd\xd3\x86\xed\xf0\x7f\xf8\x14\xdc\x7b\x8a\x0d\x53\x3b\x84\x65\x05\x97\x57\xb0\x2c\xde\x7b\x60\xeb\x59\xf5\x7b\x82\x1b\xbf\x50\x4d\x90\xc4\xf8\x10\x79\xb0\xf8\xc7\x90\x27\xaa\xaa\x91\xab\x03\x1a\x87\x3f\xa1\x31\xba\x41\xe3\x9e\x8e\x64\xb3\x98\x79\x88\x79\x54\x47\xb3\x18\x0e\xd9\x6f\x89\x19\x61\xc8\xe8\x96\xef\xd0\x02\xc5\xec\x0d\x97\xc8\x77\x61\x05\x53\x96\xa6\x8c\x68\xfd\x17\x12\xc2\x31\x21\xda\xa9\xfc\x40\x28\xa8\x5b\xc7\x9c\xd0\xca\x0e\x79\x0c\xb8\x31\x8d\x71\xdb\x91\x04\x96\xae\x6e\xa4\x8f\xb1\x31\x42\xb9\x0a\x72\x2e\x98\xc4\xd2\x6d\x5e\xd9\x8d\xef\x8f\x4d\x19\x03\xb7\xbe\x13\x22\x1d\x10\x1b\xe1\xe7\x58\xe4\x01\x86\x2a\x7c\x4d\xe5\x1f\x26\x4e\xc3\x1e\x98\x11\x6c\x2b\xf1\x39\x6c\xd7\x81\xa8\x60\xcf\xec\xc3\x1c\xfa\xef\x3c\xce\x1b\x4f\x54\xa0\x7d\x9f\x7c\x60\xf6\x06\x2b\xd6\x4a\x17\x06\x5f\x99\x14\x9c\x39\x6d\xac\x6f\xa2\xb6\xfe\xa0\xf5\x77\x1b\x96\x3e\x6b\x29\x4a\x7f\xc2\x19\x00\x00\x1d\x9d\x1a\x0c\xe8\x60\x47\xf3\xc4\x44\x54\xc7\x36\xbf\x04\xb8\x02\xc6\x79\x32\x7e\x93\x82\xc4\xb8\x17\x03\xa0\x4a\x1c\x51\x99\x7c\xd2\x0e\xc1\xed\x99\xa3\x52\x18\x59\x83\x2d\x4a\xfd\x08\xcc\xf8\x02\x10\x4e\x30\x29\xfe\x44\x0e\xdb\xa7\xa0\x86\xad\x72\xa2\xc6\x80\xd0\x44\xf5\xd2\xa1\xe6\x47\x73\x2a\x99\xa0\x94\x08\xac\x69\xa4\x28\x69\xaa\x80\x87\x3d\x1a\xac\xb4\xc1\xf3\x80\x20\x1c\xd8\xbd\x6e\x25\x87\x2d\x42\x50\x33\x1c\x15\xa1\x66\x42\x01\xb3\x50\x69\x29\xf5\xa3\xbd\xa4\x2d\xf4\xb3\x08\xa6\xf0\x2d\x8a\xc2\xb5\x56\x95\xd8\x8d\x6a\xda\xf7\x9b\x18\x67\x1e\xf7\xa4\x84\x1c\x98\xf1\x22\x79\x82\x98\x45\xf8\xff\x7f\x8f\x9b\xac\xfc\x81\xca\x15\x7e\x10\x37\x0e\x60\xa7\xc5\x27\xa0\x45\x27\xcc\x2b\x7f\x55\x0c\x55\xb3\x52\xda\xf9\xf1\x9d\xbd\x55\x6d\xbd\x8e\xb6\xa1\xb3\x79\xb4\x09\x7a\x15\x77\xc4\x2e\x23\xab\xd8\xe1\x83\xdd\xac\xc9\x87\xc9\x03\x93\x2d\x9d\x4b\x69\x30\x9c\x46\xa5\xcd\xd0\xf2\x89\x7a\x91\x2c\x15\xd1\xf9\x0c\x73\x2a\x77\x1f\xe6\x83\xa8\x31\xfc\xfb\xf2\xe5\xee\x06\xfa\xbe\x6a\x55\xb9\x5a\xc3\xd8\x1f\x01\xf6\xc1\x5f\x1c\x53\xe2\x23\x49\x23\xd7\x55\xf1\xa5\xe1\xcc\xe1\xcd\xe8\xe8\x54\xe2\x33\xbb\xdf\x4e\xbf\x25\x94\xdf\x4c\x7e\xca\xfc\xb7\xf2\xa5\x5b\x7f\x59\x15\x89\x3a\xa4\xe9\x92\xc4\x86\x5c\x47\x8b\x99\x01\xdd\xc2\x97\x57\x30\x0a\x9d\x8f\x01\x56\xaf\xec\x1a\xd0\x18\x6d\xf2\x67\x11\x0c\xcc\xa8\x98\x9e\xb0\xc0\x3c\x13\x11\x7a\xe0\x20\x9f\x91\x90\x47\x16\xe0\xce\xf9\x0d\x25\x93\x72\x6a\xf6\x6d\x2b\x24\x47\xe3\x25\xc1\xf7\x2c\x58\x76\xc0\x89\xaf\xc1\x0f\x49\xf2\x09\x22\xd2\xc1\x7a\xae\xa6\x9b\xb3\xe1\xb5\x54\xb6\xd6\xe9\x3a\xbc\x3a\x7c\x94\xa8\xda\x3a\x84\x65\x81\x5e\x56\xd3\x6d\xf8\xed\xfc\xc8\x1d\x4f\xf2\x3d\x9c\x97\x6f\xa8\xc1\xf7\xe6\x0c\x74\x2d\x82\xbe\x0d\x5a\x45\x51\x57\xc6\xfb\xdb\x23\xf9\x2c\x82\x93\x78\xbf\xf9\xed\x97\x57\xe0\x8c\xa8\x07\x39\x89\x34\x17\xf7\xe1\x06\x5d\x26\x3a\x93\x5c\xb8\xc1\x6f\xcc\xc9\x8e\xe8\x27\x6a\x6f\xca\xd1\x13\x4a\x86\x29\x4a\xb8\xac\xb3\x2c\xed\x9c\x79\xcf\xf8\xf9\xcd\x19\x40\x25\x14\x27\x7c\xda\x4a\x72\x7e\xa2\x1f\x7c\x9e\xf1\xd9\x93\xaa\x96\xa7\x74\x28\x44\x4f\xde\xac\x4a\x45\x05\xf8\xc3\xaf\x4f\xfe\xbf\x52\x6f\x45\x9b\x17\xa5\xec\x11\x28\xc7\xe5\x64\xf3\xb2\x2e\xd3\xd8\x92\xb4\x43\x6d\x2d\xc2\x3b\x36\xf0\x35\x17\x00\xb8\x4a\x91\xc6\x28\xe7\x7d\x77\xac\xf8\x5e\x9e\x13\x51\x42\xcf\x9a\xf1\xd9\xfc\x6f\x69\x79\x99\xe7\x0c\x79\x78\x1a\x85\x57\x51\x00\x9d\x82\x5a\xfb\x58\x42\x27\xdb\x74\xdb\x1a\x42\x79\xad\xd6\xc3\x4b\xad\xf3\x9b\x0d\xba\xd6\xa8\x38\xb5\xb2\xeb\x6c\xb1\xe8\xb3\x2c\x69\xc0\xe7\x0a\x72\x31\x96\x32\x33\x3b\xbf\x6a\xb0\x44\x71\x08\x8f\xd6\xff\x86\x86\x7e\x1f\x1f\xa3\xd9\x2f\x69\x86\xc7\x1b\x05\x23\x94\x5b\x24\xf1\x97\xc4\x83\x72\x4f\x7c\xae\x26\xec\x39\x1f\x24\x72\x81\x05\xfb\x28\x5c\xb9\x87\xd4\x92\xce\xa2\x64\x96\xfa\x26\x9e\x99\x38\x72\x66\x41\x1a\x94\x5f\x85\xd7\xd0\xf7\xe7\xcf\x24\xfc\xde\x99\xb6\x74\x03\x23\x5d\x07\x0d\xb3\x25\x93\xe1\xfc\x46\xdb\xcb\x50\x99\xf1\x34\x94\x90\x34\x8e\x25\x3c\x5f\xac\x6a\x57\xdc\xfa\xd0\xab\x55\x78\x9c\x4c\x6a\x71\x09\x42\x11\xb9\x09\x7b\xc4\xf1\x91\x7b\xe9\x12\x5e\xfd\xc8\xcf\x93\x94\xfd\xd1\x2f\x7a\x3a\xff\xc5\x24\xa4\xa7\xbe\x0c\xe9\x25\xcc\x38\x17\xfe\xf2\x67\x72\xf8\x44\x7c\xae\xc0\xef\xa6\x2d\x24\x1d\x25\x53\xfe\x25\xa6\x0f\x68\x8c\xe0\xe1\x29\xa6\x0d\x7d\x3e\x6b\x7a\x6c\x4e\x90\xe1\x3b\x7b\xa8\x10\x52\xb0\xa8\xb1\xc5\xa8\xda\xe9\xe7\xf0\x2c\x9a\x84\xda\xec\xaf\x00\x00\x00\xff\xff\x9e\x2c\x22\x88\xfb\x0f\x00\x00") func templateMetaTmplBytes() ([]byte, error) { return bindataRead( @@ -895,7 +939,7 @@ func templateMetaTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/meta.tmpl", size: 4878, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/meta.tmpl", size: 4091, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -920,7 +964,7 @@ func templateMigrateMigrateTmpl() (*asset, error) { return a, nil } -var _templateMigrateSchemaTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x4b\x6f\xe3\x36\x10\x3e\x4b\xbf\x62\x20\xb8\xc5\x6e\x60\x4b\x49\x6e\x35\xe0\x43\x90\xcd\x02\xc1\x16\xe9\xa2\xc9\x9e\x82\xa0\x60\xa8\x91\x45\x58\x22\x15\x8a\x4a\xe3\xaa\xfa\xef\x05\x1f\x92\xe8\x57\xec\xed\x6e\x2e\x16\xc9\x79\x70\xbe\xf9\x66\x86\x69\xdb\xe4\x2c\xbc\x16\xd5\x5a\xb2\x65\xae\xe0\xf2\xfc\xe2\xb7\x59\x25\xb1\x46\xae\xe0\x33\xa1\xf8\x2c\xc4\x0a\x6e\x39\x8d\xe1\xaa\x28\xc0\x08\xd5\xa0\xcf\xe5\x2b\xa6\x71\xf8\x90\xb3\x1a\x6a\xd1\x48\x8a\x40\x45\x8a\xc0\x6a\x28\x18\x45\x5e\x63\x0a\x0d\x4f\x51\x82\xca\x11\xae\x2a\x42\x73\x84\xcb\xf8\xbc\x3f\x85\x4c\x34\x3c\x0d\x19\x37\xe7\xbf\xdf\x5e\xdf\xdc\xdd\xdf\x40\xc6\x0a\x04\xb7\x27\x85\x50\x90\x32\x89\x54\x09\xb9\x06\x91\x81\xf2\x9c\x29\x89\x18\x87\x67\x49\xd7\x85\x61\xdb\x42\x8a\x19\xe3\x08\x51\x4d\x73\x2c\x49\x04\x76\x7b\x06\x7f\x33\x95\x03\xbe\x29\xe4\x29\x4c\x20\xfa\x4a\xe8\x8a\x2c\x31\x82\xa8\x64\x4b\x49\x14\x46\x30\xeb\xba\x30\x68\x5b\x50\x58\x56\x05\x51\x08\x51\x8e\x24\x45\x19\x41\xac\xad\xb4\x2d\x68\x5d\x6d\x8f\x95\x95\x90\x0a\x3e\x18\x71\x49\xf8\x12\x61\xf2\xd7\x14\x26\x1c\xe6\x0b\x98\xc4\x77\x22\xc5\x5a\x0b\x06\x41\xd4\xb6\x30\x89\xaf\x05\xcf\xd8\x32\x76\x3e\xa1\xeb\x12\xbd\xcd\xbd\x8d\x48\x9b\x9a\x0d\x0e\x82\x68\xc9\x54\xde\x3c\xc7\x54\x94\x49\xe6\xc0\x67\x9c\x36\xcf\x44\x09\x99\x20\x57\x89\x8d\x2f\xc9\x18\x16\x69\x74\x8a\x42\xca\x48\x81\x54\x25\xf5\x4b\xe1\x94\xa3\xf0\x63\x18\xbe\x12\x69\x03\x99\xf9\x91\x28\x1b\xc9\x03\x79\x2e\xfa\x50\xb4\x44\x72\x06\x19\xe3\x29\xa8\x75\x85\xc0\x4d\x96\x6d\x8a\x96\x92\x54\xf9\x90\x19\xa5\xd5\xa6\xc0\x32\xc0\x37\x56\xab\x1a\x4c\x76\xac\x89\x89\x51\x9b\x2f\x80\xf1\x14\xdf\x06\xb4\xce\x47\x27\x87\x01\x6d\x5b\x63\xf3\x05\x26\x2a\xbe\x23\x25\x6a\x0c\xcd\x15\xed\x99\x35\xbd\xd0\x6a\x66\x6d\xd1\x1c\xf3\xe6\x2e\x40\x45\xd1\x94\xbc\xd6\xa6\x2b\x52\x53\x52\x0c\xe6\xfe\x85\x4a\x32\xae\x32\x88\x7e\xa9\xaf\xad\x54\x64\x15\x93\x04\xb4\x83\x5e\xb5\xeb\x20\x17\x45\x5a\x9b\xd8\xfb\xcd\x4c\x58\x8a\x9b\x9c\x3b\x8b\x5d\x17\x59\x34\x62\xe3\x7d\xc3\xc2\x02\x1e\x9f\xce\x6c\x26\x62\xeb\xad\x0d\x83\x1d\x08\xa8\x81\x40\x39\x09\x97\x8b\x20\x68\x41\xdb\x9f\x5b\x67\x74\x70\x36\x85\x87\x75\x85\x73\x30\xb4\x88\xed\x99\xde\xd1\x14\xac\x95\x93\x9a\x5a\x0b\xed\x4c\xa3\x39\xa1\xf1\x37\xce\x5e\x1a\x7d\x00\xf6\x6b\x0e\x4a\x36\x38\xf5\x81\xf3\xc5\x6f\x39\x95\x58\xea\xb6\xd0\x75\x30\x2c\x8e\x28\xdd\x35\x45\xe1\x32\x05\xfd\xf7\x1c\xdc\xe5\xc7\xb3\x3d\xfa\xa6\x70\x27\x34\xbe\x67\xff\x18\x6d\xfd\x6b\x34\xe3\xf7\xe5\xaf\x94\x92\x5a\x5e\xff\x5a\x9c\x62\x83\xd0\x61\x8d\x1b\xde\x94\x26\x33\xe6\x63\x0e\x8f\x4f\xb5\x92\x8c\x2f\x5b\x18\xcb\x9c\x4d\x61\x62\xe8\x6b\x8c\xe9\xfb\xe3\xa6\x55\x78\xef\x4e\x9f\x30\x23\x4d\x61\x80\x73\x9f\x16\x03\x4d\x5c\xaf\x1b\xc4\x3b\xd1\xd9\x9c\x79\x2d\x22\x08\x06\x3e\x1b\x7e\x1d\x61\xb3\xa9\x92\x4d\x2e\xab\x3e\x1d\x23\x93\x2d\x19\x81\xf1\x4c\xc8\x92\x28\x26\xf8\x69\xa4\x1e\x4c\x2d\xe0\x57\x47\x68\xe3\xd0\xf0\xd9\xe3\xe9\xa8\x6f\xc2\x71\x94\x9e\x6f\x95\x96\x39\xfb\x2a\x59\x49\xe4\xfa\x0b\xae\xe7\xfb\xcb\x64\xbb\x4e\xaa\x95\x2b\x94\x51\xb3\xcf\x80\x2f\xca\x0e\x97\xd4\x40\x57\xdd\x60\xaa\x95\xeb\x30\x43\x6d\x6d\x5e\xf2\x51\x2f\x19\x74\xdd\xd3\x56\xba\x37\x93\xb4\xbd\xb4\xc1\x7d\x16\x12\xd9\x92\x7f\xc1\x75\xed\x47\x37\x6e\xef\x8d\x30\xeb\x23\xf4\xd4\x47\xaf\x2e\x84\xfb\x75\xf9\x2c\x0a\x87\x77\xb6\x8a\xed\x7a\x80\xdc\x47\x7d\x3f\xac\x01\xc0\x6e\x0f\xba\x30\x9e\xb3\xd5\x2e\x64\xbb\xe0\x5e\x1e\x42\x77\x13\x60\x7a\xd1\x03\x7c\xf9\xbd\x08\xef\x82\xbc\x6f\xa7\x9b\x0e\x59\x4d\xce\xa0\x12\xb5\xaa\x04\x47\x90\x98\x49\xe4\x94\xf1\x25\x28\x01\xe4\x55\x30\x3b\xce\x68\x8e\x74\xa5\x77\x0b\x21\xaa\x61\x62\xe9\xbf\x3f\x31\xfb\x21\xcc\x46\xfd\xe3\xb0\x59\x71\x53\x3c\xff\x0f\xc0\xbe\x07\xf8\x86\xde\x9b\x6d\x3f\x11\xe5\xbe\xcd\x65\xab\xf8\x0f\xfe\xad\x4a\x89\xda\x1c\x3b\xbd\x8d\xfe\x70\xee\xfa\xcd\xd0\xed\xc2\x03\x3e\xb6\x4c\x7f\xc2\x02\x0f\x9a\xb6\x87\xa7\x9a\xf6\x46\xe1\x76\x8d\xf6\xa3\x4b\xc5\xb7\xfa\xa1\x82\x43\x1e\xdc\xd2\xe7\x82\xd9\x6a\x77\x7a\x8d\xa6\x01\x4b\xdf\x5c\x3d\x6c\x99\x19\x4b\xd6\xef\x90\x2c\x7d\xdb\xec\x91\xfa\xaf\x9f\xca\xbd\xc0\x30\xaf\x07\x89\x63\xfc\xdc\xf3\xac\xb0\xf4\xd4\xe6\x0e\xf1\xec\xd4\xa2\xfe\x79\x55\xbd\x87\x70\x7b\xb6\x86\xb0\xfb\x8f\x2d\x91\xfd\xb3\xd2\x5f\x27\x09\xb8\x97\xad\x9d\x7d\xa4\x28\xcc\x90\x53\x76\xd3\xbd\x69\x1d\x90\x61\xe0\x64\xfd\xf7\xda\x30\xde\x8e\xbf\x9b\x03\xaf\x2a\xdf\x9b\xcc\xd3\x70\xf3\xd2\x9d\x7e\x9d\x67\x0d\xa7\xc0\x38\x53\x1f\x3e\x42\x7b\xea\x2b\xfd\xbb\x5f\x04\x5b\xd9\x7e\x67\xd0\xf8\xd3\xde\x3f\x1e\xd3\x3a\xb4\x1d\x58\xc0\xa9\xfd\x68\xfb\x2e\x3d\x04\xde\xb7\xfd\xe7\xce\x2d\xfe\x0b\x00\x00\xff\xff\x7a\x4a\xf3\x99\xab\x0e\x00\x00") +var _templateMigrateSchemaTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x5b\x6f\xdb\x36\x14\x7e\x96\x7e\xc5\x81\xe0\x0d\x6d\x60\x4b\x49\xde\x66\xc0\x0f\x41\x9a\x02\x41\x87\xac\x58\xd2\xa7\x20\x18\x18\xea\xc8\x22\x2c\x91\x0a\x45\x65\xf1\x34\xfd\xf7\x81\x17\x49\xf4\x2d\x76\xd7\xe6\xc5\xe2\xb9\xf2\x7c\xe7\xc6\xb4\x6d\x72\x16\x5e\x8b\x6a\x2d\xd9\x32\x57\x70\x79\x7e\xf1\xdb\xac\x92\x58\x23\x57\xf0\x99\x50\x7c\x16\x62\x05\xb7\x9c\xc6\x70\x55\x14\x60\x84\x6a\xd0\x7c\xf9\x8a\x69\x1c\x3e\xe4\xac\x86\x5a\x34\x92\x22\x50\x91\x22\xb0\x1a\x0a\x46\x91\xd7\x98\x42\xc3\x53\x94\xa0\x72\x84\xab\x8a\xd0\x1c\xe1\x32\x3e\xef\xb9\x90\x89\x86\xa7\x21\xe3\x86\xff\xfb\xed\xf5\xcd\xdd\xfd\x0d\x64\xac\x40\x70\x34\x29\x84\x82\x94\x49\xa4\x4a\xc8\x35\x88\x0c\x94\xe7\x4c\x49\xc4\x38\x3c\x4b\xba\x2e\x0c\xdb\x16\x52\xcc\x18\x47\x88\x6a\x9a\x63\x49\x22\xb0\xe4\x19\xfc\xcd\x54\x0e\xf8\xa6\x90\xa7\x30\x81\xe8\x2b\xa1\x2b\xb2\xc4\x08\xa2\x92\x2d\x25\x51\x18\xc1\xac\xeb\xc2\xa0\x6d\x41\x61\x59\x15\x44\x21\x44\x39\x92\x14\x65\x04\xb1\xb6\xd2\xb6\xa0\x75\xb5\x3d\x56\x56\x42\x2a\xf8\x60\xc4\x25\xe1\x4b\x84\xc9\x5f\x53\x98\x70\x98\x2f\x60\x12\xdf\x89\x14\x6b\x2d\x18\x04\x51\xdb\xc2\x24\xbe\x16\x3c\x63\xcb\xd8\xf9\x84\xae\x4b\x34\x99\x7b\x84\x48\x9b\x9a\x0d\x0e\x82\x68\xc9\x54\xde\x3c\xc7\x54\x94\x49\xe6\xc0\x67\x9c\x36\xcf\x44\x09\x99\x20\x57\x89\x8d\x2f\xc9\x18\x16\x69\x74\x8a\x42\xca\x48\x81\x54\x25\xf5\x4b\xe1\x94\xa3\xf0\x63\x18\xbe\x12\x69\x03\x99\xf9\x91\x28\x1b\xc9\x03\x79\x2e\xfa\x50\xb4\x44\x72\x06\x19\xe3\x29\xa8\x75\x85\xc0\x4d\x96\x6d\x8a\x96\x92\x54\xf9\x90\x19\xa5\xd5\xa6\xc0\x32\xc0\x37\x56\xab\x1a\x4c\x76\xac\x89\x89\x51\x9b\x2f\x80\xf1\x14\xdf\x06\xb4\xce\x47\x27\x87\x01\x6d\x5b\x63\xf3\x05\x26\x2a\xbe\x23\x25\x6a\x0c\xcd\x15\x2d\xcf\x9a\x5e\x68\x35\x73\xb6\x68\x8e\x79\x73\x17\xa0\xa2\x68\x4a\x5e\x6b\xd3\x15\xa9\x29\x29\x06\x73\xff\x42\x25\x19\x57\x19\x44\xbf\xd4\xd7\x56\x2a\xb2\x8a\x49\x02\xda\x41\xaf\xda\x75\x90\x8b\x22\xad\x4d\xec\x3d\x31\x13\xb6\xc4\x4d\xce\x9d\xc5\xae\x8b\x2c\x1a\xb1\xf1\xbe\x61\x61\x01\x8f\x4f\x67\x36\x13\xb1\xf5\xd6\x86\xc1\x0e\x04\xd4\x40\xa0\x9c\x84\xcb\x45\x10\xb4\xa0\xed\xcf\xad\x33\x3a\x38\x9b\xc2\xc3\xba\xc2\x39\x98\xb2\x88\x2d\x4f\x53\x74\x09\xd6\xca\x49\x4d\xad\x85\x76\xa6\xd1\x9c\xd0\xf8\x1b\x67\x2f\x8d\x66\x80\xfd\x9a\x83\x92\x0d\x4e\x7d\xe0\x7c\xf1\x5b\x4e\x25\x96\x7a\x2c\x74\x1d\x0c\x87\x23\x4a\x77\x4d\x51\xb8\x4c\x41\xff\x3d\x07\x77\xf9\x91\xb7\x47\xdf\x34\xee\x84\xc6\xf7\xec\x1f\xa3\xad\x7f\x8d\x66\xfc\xbe\xfc\x95\x52\x52\xcb\xeb\x5f\x8b\x53\x6c\x10\x3a\xac\x71\xc3\x9b\xd2\x64\xc6\x7c\xcc\xe1\xf1\xa9\x56\x92\xf1\x65\x0b\x63\x9b\xb3\x29\x4c\x4c\xf9\x1a\x63\xfa\xfe\xb8\x69\x15\xde\xbb\xd3\x27\xcc\x48\x53\x18\xe0\xdc\xe7\x9e\x48\x6c\x7e\xbc\x71\x10\x04\x43\xed\x9a\x5a\x3a\x52\xb9\xa6\x23\x36\xeb\x56\xf5\xd0\x8f\x55\x6b\x0b\x0f\x18\xcf\x84\x2c\x89\x62\x82\x9f\x56\xc0\x83\xa9\x05\xfc\xea\x8a\xd7\x38\x34\xb5\xeb\xd5\xe4\xa8\x6f\xc2\x71\xe5\x3b\xdf\x6a\x23\xc3\xfb\x2a\x59\x49\xe4\xfa\x0b\xae\xe7\xfb\x5b\x62\xbb\x27\xaa\x95\x6b\x8a\x51\xb3\x47\xdb\x17\x65\x87\xdb\x67\x28\x4d\x3d\x4c\xaa\x95\x9b\x26\x43\x1f\x6d\x5e\xf2\x51\x1f\x19\x74\xdd\xd3\x56\x6a\x37\x93\xb4\x7d\xb4\xc1\x7d\x16\x12\xd9\x92\x7f\xc1\x75\xed\x47\x37\x92\xf7\x46\x98\xf5\x11\x7a\xea\xa3\x57\x17\xc2\xfd\xba\x7c\x16\x85\xc3\x3b\x5b\xc5\xf6\x3c\x40\xee\xa3\xbe\x1f\xd6\x00\x60\x77\xde\x5c\x18\xcf\xd9\x6a\x17\xb2\x5d\x70\x2f\x0f\xa1\xbb\x09\x30\xbd\xe8\x01\xbe\xfc\x5e\x84\x77\x41\xde\x47\xe9\xa6\x43\x56\x93\x33\xa8\x44\xad\x2a\xc1\x11\x24\x66\x12\x39\x65\x7c\x09\x4a\x00\x79\x15\xcc\xae\x2e\x9a\x23\x5d\x69\x6a\x21\x44\x35\x6c\x27\xfd\xf7\x27\x66\x3f\x84\xd9\xa8\x7f\x1c\x36\x2b\x6e\x9a\xe7\xff\x01\xd8\xcf\x00\xdf\xd0\x7b\x7b\xec\x27\xa2\xdc\x8f\xb4\x6c\x15\xff\xc1\xbf\x55\x29\x51\x9b\x2b\xa6\xb7\xd1\x33\xe7\x6e\xde\xc4\xfd\xb4\x0b\x0f\xf8\xd8\x32\xfd\x09\x0b\x3c\x68\xda\x32\x4f\x35\xed\xad\xbd\xed\x1e\xed\xd7\x94\x8a\x6f\xf5\xa3\x04\x87\x3c\xb8\xa3\x5f\x0b\x86\xd4\xee\xcc\x1a\x5d\x06\x2c\x7d\x73\xfd\xb0\x65\x66\x6c\x59\x7f\x42\xb2\xf4\x6d\x73\x46\xea\xbf\x7e\x03\xf7\x02\xc3\x6e\x1e\x24\x8e\xd5\xe7\x9e\x27\x84\x2d\x4f\x6d\xee\x50\x9d\x9d\xda\xd4\x3f\xaf\xab\xf7\x14\xdc\x1e\xd2\x10\x76\xff\xb1\x25\xb2\x7f\x57\xfa\xe7\x24\x01\xf7\x8a\xb5\xbb\x8f\x14\x85\x59\x72\xca\x12\xdd\xfb\xd5\x01\x19\x06\x4e\xd6\x7f\x9b\x0d\xeb\xed\xf8\x1b\x39\xf0\xba\xf2\xbd\xcd\x3c\x0d\x37\x2f\xdd\xe9\x97\x78\xd6\x70\x0a\x8c\x33\xf5\xe1\x23\xb4\xa7\xbe\xc8\xbf\xfb\x45\xb0\x95\xed\x77\x16\x8d\xbf\xed\x7d\xf6\x98\xd6\x61\xec\xc0\x02\x4e\x9d\x47\xdb\x77\xe9\x21\xf0\xbe\xed\x3f\x72\xee\xf0\x5f\x00\x00\x00\xff\xff\x8f\x25\xa0\x37\x97\x0e\x00\x00") func templateMigrateSchemaTmplBytes() ([]byte, error) { return bindataRead( @@ -935,7 +979,7 @@ func templateMigrateSchemaTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/migrate/schema.tmpl", size: 3755, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/migrate/schema.tmpl", size: 3735, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -960,7 +1004,47 @@ func templatePredicateTmpl() (*asset, error) { return a, nil } -var _templateTxTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x4d\x8f\xdb\x36\x10\x3d\x4b\xbf\x62\x6a\x2c\x0a\x7b\xe1\x50\x69\x6e\x5d\x60\x0f\xc1\x26\x05\x02\xb4\x0b\xb4\xeb\xa2\xb9\x25\x34\x39\xb2\x88\x48\xa4\x4b\x8d\x6c\x19\x86\xff\x7b\x31\x24\x25\xd9\xbb\x4e\xd3\x16\xbd\x64\x2d\x72\x3e\xde\x0c\xdf\x3c\x32\xc7\x63\x71\x9b\x3f\xb8\xed\xc1\x9b\x4d\x45\xf0\xe6\xf5\x0f\x3f\xbe\xda\x7a\x6c\xd1\x12\xfc\x24\x15\xae\x9d\xfb\x02\x1f\xac\x12\xf0\xb6\xae\x21\x18\xb5\xc0\xfb\x7e\x87\x5a\xe4\xab\xca\xb4\xd0\xba\xce\x2b\x04\xe5\x34\x82\x69\xa1\x36\x0a\x6d\x8b\x1a\x3a\xab\xd1\x03\x55\x08\x6f\xb7\x52\x55\x08\x6f\xc4\xeb\x61\x17\x4a\xd7\x59\x9d\x1b\x1b\xf6\x7f\xfe\xf0\xf0\xfe\xf1\xe9\x3d\x94\xa6\x46\x48\x6b\xde\x39\x02\x6d\x3c\x2a\x72\xfe\x00\xae\x04\x3a\x4b\x46\x1e\x51\xe4\xb7\xc5\xe9\x94\xe7\xc7\x23\x68\x2c\x8d\x45\x98\x51\x3f\x83\xb4\x44\xd8\x6c\x6b\x49\x08\xb3\x0a\xa5\x46\x3f\x83\x9b\xb0\x65\x9a\xad\xf3\x04\xf3\x3c\x9b\x29\x67\x09\x7b\x9a\xe5\xd9\xac\x3d\x58\x35\xcb\xf3\x6c\xb6\x31\x54\x75\x6b\xa1\x5c\x53\x94\xa9\x7e\x63\x55\xb7\x96\xe4\x7c\x81\x96\x0a\x6d\x64\x8d\x8a\x66\xf9\x22\xcf\x8b\x02\x56\x3d\xd7\x2c\x81\xbc\xb4\xad\x54\x64\x9c\x95\x35\xa8\xda\x70\x07\xa9\x92\xc4\xdb\xca\xa3\x24\xd4\xb0\x3e\x80\x92\x75\x6d\xec\x06\x1e\x82\x85\x58\xf5\xf3\x85\xc8\xe9\xb0\x45\x8e\xd4\x92\xef\x14\xc1\x31\xcf\x94\xb3\xa5\xd9\xe4\xd9\xf1\x08\x5e\xda\x0d\xc2\xcd\xa7\x25\xdc\x58\xb8\xbb\x87\x1b\xf1\xe8\x34\xb6\xf0\xea\x74\xca\xb3\xac\x28\xe0\x78\x84\x1b\x2b\x1e\x65\x83\x70\x3a\x71\x3a\x6e\x5f\x42\x50\x3a\x0f\xc6\x12\x7a\x86\x66\x37\xb0\x37\x54\x85\xfd\x4b\xa7\x75\x67\x6a\x8d\xbe\x15\x79\x96\x5d\xee\xdc\x5e\x7c\x46\xd4\x01\x16\x5a\xcd\xfd\x3c\x85\x2e\x3c\xb8\xa6\x31\x04\x2a\xfc\x89\x00\xce\x1a\x22\xf2\xb2\xb3\x0a\xe6\xd4\xc3\xed\xaa\x5f\x24\xeb\xf9\x02\xd0\x7b\xe7\xb9\x5c\x8f\xd4\x79\x0b\xd4\x8b\x58\xb8\xd0\xde\xec\xd0\x8b\xf9\x2d\xf5\xef\xc2\xcf\x85\xa0\x5e\x0c\x8e\x29\xeb\x6f\xae\xae\xd7\x52\x7d\x01\x9f\x7e\x7c\x33\xf3\xe0\xf1\x1f\x72\x4f\xae\x43\xcd\xb1\xc3\xd1\x9d\x29\xf0\x70\x76\xe8\x6b\x63\x75\x0b\xe4\x40\x75\xde\x87\xd5\xbf\x69\x47\xf0\x9b\x2f\xe0\x36\x45\x98\x40\x7d\x1f\x57\x8e\x79\x96\x18\x71\x37\xe1\x5c\x86\xb3\x7a\x05\xa6\x84\x1b\xf1\xd4\x6d\x99\xd6\xbf\x98\x8d\x67\xce\x07\x6a\x64\x4f\xaa\xc2\x46\xde\x41\x13\x57\xc5\x23\xee\xe3\xd2\x9c\xfa\x54\xe5\x62\x88\x92\x8e\x33\xfb\x36\xe3\x2e\x09\x72\x07\x8f\xb8\xbf\xc2\x91\xf9\x88\x33\xa5\x08\x19\x42\x84\x40\x1a\x16\x1e\x28\x8d\x6f\x09\x2c\x0b\x07\x13\x55\x3b\x05\xd8\xcb\x66\x5b\x23\x84\xd1\x66\x60\x37\xd1\xe8\xee\x1e\x8c\xd5\xd8\x8f\x60\x5e\x87\x69\x2e\x0a\x18\x4e\x09\xf6\x5e\x6e\x23\x03\x36\x66\x87\x16\xd2\xa4\x8a\x55\x1f\x69\x2f\xc1\xba\xed\xb8\x9a\x9c\x0c\x67\x6b\xd0\x92\x8c\x47\xc3\x23\x5d\x21\x18\x8d\x32\x8c\x92\x83\x36\xb6\xf6\xfc\x04\xdb\x10\xd0\x75\x04\x52\x6b\x1e\x2b\x69\x0f\x80\x3d\x79\x19\x55\x90\x5c\x80\x31\x4d\x55\x51\xc0\x1f\x15\x5a\x90\xc3\x5a\xd0\x81\x10\x3e\xb1\x8d\x85\x60\x09\x86\x60\x83\x69\x80\x5a\x6e\xe7\x59\x0d\xc6\xb6\x24\xad\x42\x71\x36\x70\xd2\xea\x69\x0a\xa4\xc7\x50\x21\xb7\x92\x03\x84\xb9\x67\x35\x1a\x70\x04\x73\xde\xe9\x5a\xf4\xd0\x74\x2d\x05\x18\xe0\x2c\x72\xcc\x20\xb1\xd8\xb0\x00\x3b\x1f\xa4\xdb\xa5\x89\x06\xe7\xc7\x19\x7b\x39\x62\x45\xc1\xde\x1f\x4a\x90\xa0\x6a\xc7\xca\x7f\xb6\xcd\x4d\xc4\x66\x8d\x5a\xa3\x0e\x91\x2d\xa6\x44\xb0\x41\x8b\x3e\xe8\x22\x5a\x32\x64\xb0\x5d\x8e\x08\xc3\xca\x81\xe3\xca\xed\xb6\x36\xc8\xf3\xf5\x67\x87\xfe\xb0\x0c\xe5\x25\x96\xdc\x05\x19\x0b\x04\x19\xd8\x27\x7e\x65\xab\x8f\x1f\x3f\x72\x3b\x39\x52\xf0\x82\xbd\xa9\x6b\x58\x23\x60\x8f\xaa\x23\xd4\x81\x38\x95\x77\xdd\x26\xca\xa1\x4e\x14\xaa\x8c\xaa\x46\xb9\x0e\x17\xce\x95\x52\x1f\x1d\x61\x1c\xf3\x91\x7b\xa6\x05\xeb\x08\x36\xce\xbb\x8e\xf8\x2a\x6a\x65\x89\x49\xd8\x47\xa3\x49\xde\x43\xf6\x29\x2b\x42\x4b\xd2\xc7\x94\x17\xcd\x85\xd2\xbb\x46\xe4\x99\xf6\xbb\x67\xc4\x8d\x31\xfa\x41\xee\xc3\x5d\x5b\x1f\x98\x8b\x17\x80\x33\xea\xcf\x38\x94\x94\xcb\xe2\x7e\xd5\xa7\x2a\xb9\xb1\x16\xf7\xcf\xee\xaf\x44\xca\x28\x54\xc1\x7c\xae\xa8\x87\x74\x61\x8a\x87\xf8\x77\x09\x2f\x71\x2d\x60\xd2\xcd\x65\x14\xd9\x05\x57\x4c\x7d\xf8\xe2\x39\xd6\x7e\x27\x62\xc0\x45\x9e\x99\x32\x2c\x7f\x77\x0f\xd6\xd4\x6c\x38\x48\x9f\x35\x75\xf0\x60\xbd\x18\xe5\x70\x88\x7c\xa4\x9e\x95\x30\x00\xb8\xe3\x7f\x4e\x4b\x76\x48\xf5\xad\xfa\x51\x95\x9f\xf7\x93\x35\x62\x8b\x9e\xc5\x77\xc0\x4b\x0e\xe4\xce\x19\x3d\xcc\x94\xf3\xd3\x48\x85\x29\xe5\x90\x7c\x0e\xd7\x87\x4a\xc0\x53\xe5\xba\x5a\x33\xbb\xd8\x1c\x35\x38\x5b\x1f\xf8\xae\xbf\x6e\x7f\xa6\xfe\x13\x08\xee\xc7\x65\x73\x17\x30\x9f\x0e\x6e\xea\x24\x8c\xd7\x55\xa8\x18\x62\xc5\xef\xa2\xe5\x45\xd9\xc9\x7b\x98\xb6\x7f\xca\xb5\x6b\xe8\x52\xf8\xf9\x82\x29\xcc\x1c\x3b\x83\x21\xf8\x38\x27\x83\xe1\x6e\x74\x2d\xc6\x87\x11\x2b\x52\x90\x85\x21\xf4\x59\xdc\x60\x36\xdd\xc5\x30\x1d\x3d\x5c\xbc\x2b\xa6\x40\xf1\xfb\xab\x0a\x17\xb4\xf1\xf7\x4b\x75\xfb\xbc\x1a\x1e\x0e\x9f\xaf\x49\xdb\x57\x5e\x0c\xe7\x28\x9f\x3d\x57\x5e\xc2\x1c\xf9\x32\x02\x1d\xd5\xf2\x5f\x43\x1d\x62\x5d\x82\xfd\xba\xfa\xbe\x80\xfb\xf2\x8d\xf3\x12\xf0\xfb\x1e\xd5\x70\x05\xf5\x82\xbf\xae\x1f\x3c\xef\x5c\x9f\xfc\x28\xab\x91\x0e\x4b\x90\x7e\xd3\x2e\x61\x17\xab\xe4\x77\xf3\xf1\x74\xf5\x85\x95\x92\x71\xc8\xe5\xa0\xe7\xc9\x77\x78\x56\x05\xfd\x9e\xb0\x85\xcf\xeb\xe0\xc2\xd6\xff\x8c\x6e\x8c\x79\x15\xde\x4e\x7a\xf8\xf4\xfc\x05\x71\x7f\xde\xfd\xb9\x35\xf5\x22\xfc\xff\x23\x3d\xa8\xfe\x0a\x00\x00\xff\xff\xf7\x86\x03\x12\x61\x0d\x00\x00") +var _templatePrivacyTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x41\x6f\xdb\x38\x13\x3d\x4b\xbf\x62\x20\xa4\x80\xdd\xcf\xa5\xfb\xf5\xb6\x29\x72\x28\xda\x14\x28\xb0\x1b\x14\x6d\xb1\x7b\x28\x8a\x05\x23\x8e\x6c\x22\x12\x29\x90\x94\x1d\x43\xd5\x7f\x5f\x0c\x45\xc9\xb4\xe5\xa4\x69\xda\x2e\xf6\x14\x98\x1c\xbe\x19\xce\x9b\x37\x43\xa5\x6d\x97\x4f\xd3\xd7\xba\xde\x19\xb9\x5a\x3b\x78\xf1\xfc\xff\xbf\x3d\xab\x0d\x5a\x54\x0e\xde\xf2\x1c\xaf\xb5\xbe\x81\x77\x2a\x67\xf0\xaa\x2c\xc1\x1b\x59\xa0\x7d\xb3\x41\xc1\xd2\x4f\x6b\x69\xc1\xea\xc6\xe4\x08\xb9\x16\x08\xd2\x42\x29\x73\x54\x16\x05\x34\x4a\xa0\x01\xb7\x46\x78\x55\xf3\x7c\x8d\xf0\x82\x3d\x1f\x76\xa1\xd0\x8d\x12\xa9\x54\x7e\xff\xf7\x77\xaf\x2f\xaf\x3e\x5e\x42\x21\x4b\x84\xb0\x66\xb4\x76\x20\xa4\xc1\xdc\x69\xb3\x03\x5d\x80\x8b\x9c\x39\x83\xc8\xd2\xa7\xcb\xae\x4b\xd3\xb6\x05\x81\x85\x54\x08\x59\x6d\xe4\x86\xe7\xbb\x0c\xfa\xf5\x67\xb0\x95\x6e\x0d\x78\xeb\x50\x09\x38\x83\xec\x3d\xcf\x6f\xf8\x0a\xb3\xc8\xf2\x59\xd7\xa5\x49\xdb\x82\xc3\xaa\x2e\xb9\x43\xc8\xd6\xc8\x05\x9a\x0c\x18\xa1\xb4\x2d\xd0\x59\xc2\x93\x55\xad\x8d\x83\xac\x6d\xe1\x8c\xbd\xd6\xaa\x90\x2b\x16\x00\xa1\xeb\xb2\x34\xdd\x70\x03\xb3\x34\x59\x2e\x29\x59\x7a\x0b\x15\xdf\xc1\x35\x82\x41\xd7\x18\x85\x02\xae\x77\x60\x90\x8b\xe5\xd6\x48\x87\x60\x9a\x12\x2d\x38\x0d\x52\x09\x99\x93\x67\xb7\xe6\xce\xdf\xbd\xd6\xa5\xcc\x77\x1e\x09\x37\xbc\x6c\xb8\x93\x5a\x81\x5d\xeb\xa6\x14\xe0\xd0\x54\x52\x91\xbd\xbf\x1c\x57\xc0\xbd\x37\x81\xb9\xb4\x52\x2b\x96\x26\xbd\xfb\x0b\x40\x63\xb4\xb1\xec\x0a\xb7\xb3\x0c\x95\x5b\x86\x4b\x9f\x87\x13\x14\x41\x36\x4f\xbd\x9f\x37\xa8\x76\xff\x5a\xc0\x82\x9c\x45\xf1\x7a\xe7\xf7\x84\xeb\xed\xe3\x68\x3f\xde\xc8\xfa\x17\x45\x9b\x6b\xe5\xa4\x6a\x90\x8e\x92\xb1\xc2\x5b\xe7\xc1\x58\x9a\x78\xb7\xf7\xc4\x69\x69\x3f\xc4\x39\xef\x0b\xd0\x70\xb5\x42\x38\x1b\x2e\x0b\xe7\x17\x50\x4a\xeb\x20\xf3\x1c\x65\x90\xd1\xdd\x33\xc8\x08\xda\x97\x2d\x45\x45\x15\x36\x9e\xe8\xba\x22\xdc\xd1\x52\xee\x0a\x6d\x2a\xee\x1c\x0a\xd8\x1a\x5e\xd7\x28\x8e\xad\xe3\xc4\x16\x8d\xca\x27\x68\xb3\x1e\x02\xac\x33\x52\xad\x16\xc0\x81\x31\x26\x95\x43\x53\xf0\x1c\xdb\x6e\xde\x5f\x10\xda\x34\x49\x7a\xc7\x50\x54\x8e\x5d\xd2\xe2\x70\xf8\x7f\xd9\x39\x3c\xd9\x66\x0b\xa0\x10\x94\x98\xf1\xc5\xb1\x9b\x39\x63\x6c\x9e\x26\x9d\xcf\xc2\x20\x21\xb7\xab\x31\x48\xe4\x03\x72\xf1\xde\x13\x01\xb9\xae\xae\xa5\x42\x0b\x55\x53\x3a\x59\x97\xe8\x79\x0c\x0c\x4a\xe5\x34\x70\xb0\x52\xad\xca\x81\x3a\x96\x26\xd1\xf1\xcf\x5f\xe8\xc7\x87\xa6\xc4\x74\x44\xa6\x5f\xa1\x2b\x58\x4f\xe3\x78\x3f\x9f\x1e\x21\xd5\x0a\xb6\x6b\x74\x6b\x34\xc0\x7b\x77\xd2\xf6\xb2\xa0\xbe\x96\x8c\x18\xfb\x73\x94\x8e\xcb\x0d\x2f\x69\x6b\x46\x55\x82\xb7\x8e\xda\x00\xfd\x5d\x00\x2a\xc7\xfe\xe4\x65\x83\x21\x7b\x74\xf3\x79\x9a\x2e\x97\x30\x9c\x19\x6a\x0d\x2d\x70\x28\x35\x17\xc0\x57\x5c\x2a\xeb\x86\x00\x86\xbb\x79\xd2\x66\xfd\xaf\x28\x4d\x73\xd8\x7b\x77\xb7\x30\x89\x60\x33\x89\x81\x42\x2e\xb4\x81\xbf\x17\x3e\x97\x54\x7b\x7d\x39\x06\x6c\xba\x91\xdd\x4a\x97\xaf\xc9\xde\x6f\x53\x9d\xc7\x6e\x16\xb0\x99\xbf\xf4\x86\x39\xb7\xe8\xcd\x2e\x2e\x40\xc9\x12\xbe\x7e\x1d\x74\xf0\xce\xce\xd0\x98\x85\x17\xe5\xfc\x3c\x32\x8d\x37\x7d\xb9\xfb\xdd\xa1\xa6\x94\x2c\xd3\x24\x11\x58\xf0\xa6\x74\xf1\x06\x1a\x93\x26\x49\x47\x19\x8c\x6d\x3b\x9f\xcd\x81\x98\xb7\x94\x24\x5f\x4e\xd2\xcb\x82\x0b\x5e\x3b\x1a\x37\x3a\x34\x37\x22\xbd\xb1\x08\xba\xa0\x63\xda\x08\xa9\xb8\xd9\x01\x25\x97\xe4\x6e\x81\xdb\xa8\xcc\x58\x5f\x9a\x07\xe8\x64\xfa\x00\xa2\x07\x8e\x21\xe7\x65\x69\xa1\x18\xd2\x36\x10\x59\x1c\xa0\x3e\x8e\xc5\x41\x86\x03\x76\x7a\xa8\xa5\xbf\xa8\xe3\xdd\x29\xa6\xb8\x1f\xde\xa1\xa6\x18\xe0\xf3\x17\xff\x6b\xaf\xa7\xf1\xe7\xc3\x05\xd5\xbb\x3c\x50\xd4\x1e\x65\x2a\x29\xbf\x77\x3a\xd5\x7f\x34\xce\xb7\xe7\x93\xb2\xf2\xe7\x0e\x74\x55\x05\xf3\x48\x5b\x7d\x2c\x27\xc5\x15\x5d\x7b\x0e\x51\x20\xa7\x88\xa9\x4e\x85\xf3\x03\x0a\x1b\x5d\x2d\xa0\xfa\x6f\x49\x6c\x64\xea\xa7\x68\x2c\xaa\xbe\x20\xb2\x43\xfc\xbb\x55\x76\x4c\xfd\x69\xa1\x55\x91\xd0\x0e\x90\x1f\xcf\xe8\xa1\xda\xaa\x79\xc8\x4b\xd0\xc7\xca\xe8\xa6\x0e\xbd\x83\x2b\x11\xd7\x97\x1c\xef\x18\x6c\xad\x33\x4d\xee\x08\xd3\x4f\x80\x7d\x33\x0f\x7a\x88\x2b\x30\x78\x19\xc7\x45\xa1\xcd\x96\x1b\x61\xe3\x37\x8a\xd3\xf7\x8c\x8a\x1f\x19\x13\xe1\xca\x01\x97\x4e\x4f\xc6\x40\x14\x5f\x1f\xfb\x1d\x01\xde\xa3\xb7\x1f\x95\xda\x61\x94\x1e\x61\xaa\xa5\x68\x50\x44\x3d\xe7\xb8\x69\xf9\xc7\xe0\x69\x2a\x8f\x07\xc2\x1d\x9d\x6b\x7c\x74\xec\x5b\x5b\x70\xfd\xaa\xdc\xf2\x9d\xf5\x72\xf4\xc7\xc6\xd7\xdb\xf1\xfb\xb4\x8f\x22\x7a\xdc\x1d\xbf\xe4\x7d\xf6\x8e\xe0\x66\xf3\xa3\xa8\xa2\x8a\x95\xb7\x28\xde\x84\xd3\xb4\xd7\xfa\x53\xdd\x41\x5c\xf4\xe0\xfc\xae\xb0\x8e\x9f\xeb\x51\x50\x03\xd6\x77\xc5\x44\x87\xba\x71\x82\x4d\xf6\x47\xd1\xf8\x56\xd8\x73\xdf\xa5\xa3\xc6\x27\xf6\x71\xc1\x7f\x6b\x58\x43\x0b\x43\x58\x8c\xd0\xbb\x6f\xc1\x3e\x7c\x32\x4d\xa1\xe3\xf7\xbf\x7f\xf8\x9f\xb1\x2b\x2d\xd0\x42\xf8\xe2\x3c\x53\xbc\xf2\x23\xa3\x36\x52\x39\x38\x53\xec\x8a\x16\xb2\xf8\xb9\x90\x8d\xc6\x3e\x59\xa3\x71\xf6\x94\x42\xc8\xc6\x43\xe1\xc3\xe1\xd3\x1a\x61\x44\xee\xba\x07\x36\xef\xb1\x73\x7b\x8c\x83\xee\xcd\xf7\x6f\x24\x96\x26\x1e\x2e\xc6\x3f\xdd\xbc\xc7\x70\xbb\x6e\xec\xdd\x49\xdc\xda\x26\x2f\xa5\x64\xa0\x21\x02\x7f\x5c\x23\x4b\x64\x01\x9b\x05\xe8\x1b\xca\xd5\x86\xcd\xe2\x58\x5e\xd2\x72\x1b\x8d\xc1\xfd\x7b\xca\x0f\xc3\x61\x99\x0a\xb4\x38\xfa\xb4\x6b\x14\xde\xd6\x98\xd3\x77\x17\x75\x3b\xec\x53\xfb\xe4\xd3\x02\xfa\xf5\xf8\xd2\x59\x0f\xd9\xa5\x11\xcd\x13\x96\x0f\x66\xd5\x11\xcd\x27\x58\x1e\xaa\xed\x17\xb3\xbd\x6f\x02\x3f\x87\xee\x7e\x52\x4c\x06\xf6\xdd\x7c\x3f\x66\x2c\x10\xe7\xd5\xc0\x79\xf5\x30\xce\xab\xef\xe3\x7c\x7c\x57\xde\x4f\x7b\x35\xf9\xe2\xdd\xff\xff\xe8\x9f\x00\x00\x00\xff\xff\x01\x59\x8e\x14\x6b\x13\x00\x00") + +func templatePrivacyTmplBytes() ([]byte, error) { + return bindataRead( + _templatePrivacyTmpl, + "template/privacy.tmpl", + ) +} + +func templatePrivacyTmpl() (*asset, error) { + bytes, err := templatePrivacyTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "template/privacy.tmpl", size: 4971, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templateRuntimeTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x5b\x6f\x1b\xbb\x11\x7e\xd6\xfe\x8a\xa9\xa0\x02\x52\x2a\x51\x76\xde\xea\x42\x0f\x69\x2e\x38\x06\x9a\x34\x80\x93\x9c\x07\x23\x38\xa0\x76\x67\xb5\x3c\x5e\x91\x5b\x92\xeb\xd8\x10\xf6\xbf\x17\xc3\xcb\x2e\x57\x17\xa7\x38\x45\x81\xbe\x58\x4b\x72\x66\x38\xf3\xcd\x95\x3e\x1c\xd6\xaf\xb2\xb7\xaa\x79\xd6\x62\x57\x59\x78\x7d\x75\xfd\xd7\x55\xa3\xd1\xa0\xb4\xf0\x81\xe7\xb8\x55\xea\x01\x6e\x65\xce\xe0\x4d\x5d\x83\x23\x32\x40\xe7\xfa\x11\x0b\x96\x7d\xa9\x84\x01\xa3\x5a\x9d\x23\xe4\xaa\x40\x10\x06\x6a\x91\xa3\x34\x58\x40\x2b\x0b\xd4\x60\x2b\x84\x37\x0d\xcf\x2b\x84\xd7\xec\x2a\x9e\x42\xa9\x5a\x59\x64\x42\xba\xf3\x7f\xdc\xbe\x7d\xff\xe9\xee\x3d\x94\xa2\x46\x08\x7b\x5a\x29\x0b\x85\xd0\x98\x5b\xa5\x9f\x41\x95\x60\x93\xcb\xac\x46\x64\xd9\xab\x75\xd7\x65\x99\xb3\xe1\x0b\xb1\xb4\xd2\x8a\x3d\x82\xc5\x7d\x53\x73\x8b\xb0\x43\x89\x9a\x5b\x34\x4e\xa2\xc9\x2b\xdc\xf3\x95\xb1\xc2\xe6\x95\x90\x3b\xa8\xd5\x4e\xe4\xc0\x65\x01\x95\xaa\x0b\x47\x94\xed\x55\xd1\xd6\x08\x8f\xa8\x8d\x50\xa4\x09\xb7\xf0\x83\x1b\x68\xc9\x22\xab\x7a\x91\x4e\x22\x37\x06\xad\x61\x59\x76\x6b\xa1\xe2\x06\x5e\x43\xa9\xf4\x9e\x5b\xc3\xe0\x0d\x4c\x83\x3a\x53\x68\x78\xfe\xc0\x77\xe8\x85\x99\x4a\xb5\x75\x01\x5b\x04\xdc\x37\xf6\x79\x25\xf6\x8d\xd2\x16\x8b\x60\x77\xb6\xe7\x42\xf6\x1c\xa5\xd2\x41\x6d\x03\x3f\x84\xad\xa0\x52\xea\xc1\x80\xd2\xd0\xa8\x5a\xe4\x02\x0d\xcc\x1b\x65\x51\x5a\xc1\x6b\xc8\x9f\xf3\x5a\xe4\x41\xe2\x82\x39\x4c\x0c\xe6\x4a\x16\x41\x2f\x72\x4f\x34\x20\xf5\xcf\x14\xa5\xed\xd5\x5c\x3a\x44\x52\xe5\x40\x98\x4c\x2a\x0b\x12\x73\x34\x86\xeb\x67\x98\x4b\x05\xaa\xb1\x84\x10\xa9\x78\x74\x31\x9c\x5e\x1c\xe1\x7b\x40\x6c\xb2\x2d\xcf\x1f\x7e\x70\x5d\x98\x55\xae\xf6\x0d\xb7\x62\x2b\x6a\x61\x9f\xbd\x85\x8d\xc6\x47\xa1\x5a\x13\x5d\x60\xc8\xf5\x28\xed\xe0\x6d\x28\xb0\x14\x12\x7b\x80\xd7\x4e\xfb\xae\xcb\x00\x00\x0e\x87\xc1\xfd\x83\x07\x66\x74\x7c\x38\x00\xca\x02\x2e\x08\x69\x1e\x76\xa9\x10\xa7\x0b\x3e\x59\xe2\x98\xc1\xf4\xb3\xc7\x66\x9a\xc8\x0c\xb4\x97\x2f\x65\x89\xb8\x70\xf1\xe4\x70\x80\x59\x08\xb1\x9b\x0d\xcc\xd8\x47\xf7\x7d\x2b\x4b\x15\x8f\x45\x49\xee\x0d\x44\xec\x5b\x88\xc3\xb8\xbe\x6b\xf7\x8e\x30\x57\xd2\x58\x98\x67\x93\xc9\xe1\xb0\xf2\xca\x1e\xb3\x10\xd9\x64\x12\x57\x1b\x98\x1e\x0e\x4e\xa5\x29\xac\xd7\x10\xb7\x3d\xb6\x2e\x77\x77\x28\x59\x90\x17\xb5\x3d\x15\x1e\xef\x9f\x4c\xe8\xeb\x48\x28\x6d\xbd\x2c\x70\xe1\x4c\x0c\xab\x17\xfd\x31\x8d\xfb\x03\xb0\x15\xf2\x02\x75\xc0\x95\x8e\x66\x3e\x1b\x6e\x36\x70\x15\xe4\x69\x2e\x77\x08\x33\xe9\xc1\xfd\xa4\x0a\x34\x3d\xec\xb2\xdd\xff\x12\xe9\x67\x92\x7d\x8a\xcb\xae\xf3\xa8\xcf\x24\xfb\x85\x9b\xcf\x94\x57\xcf\x7e\x73\x60\xd9\x00\x2f\x8a\x64\x7d\xed\x09\x52\xaf\x56\x29\xa1\x5f\x0c\xf4\x23\x6b\x89\x5a\xdb\xe6\x61\x47\x9a\x94\xbc\x36\xd8\xeb\x50\x71\xf3\x41\x60\xed\x42\xee\x2e\x57\x8d\x83\x61\xa0\xdf\x00\xfe\x0b\x66\xcc\x9d\xb0\x10\x92\x23\xc4\xc6\x90\x92\x51\x9e\xb1\xeb\x80\xaa\x24\x5c\x1b\x1b\x33\x72\x15\xcb\xe5\x3a\xfc\xb2\x9d\x02\x97\x62\x21\x0a\x83\x11\x31\x88\x27\xe7\x82\x7c\xad\x71\x27\x8c\x25\xaf\xcc\x22\x12\xe8\x0d\xca\x26\x93\xf5\xda\x57\x82\xf3\x75\x77\x54\x8b\x84\xa4\x2c\x99\xb1\xb7\x4a\x96\x62\xd7\xdb\xd6\x75\x89\x76\xc7\xb1\x13\x81\x5b\xbf\x82\xd7\x43\xa5\xa1\x60\xb3\x97\x6c\xa2\x2a\xf6\xff\x65\xd7\x0b\xf6\x9d\x64\x89\xeb\x74\x10\x55\x0b\xf7\x43\xc5\x65\x51\xa3\x36\x54\x5e\xed\x73\x83\xb1\x8e\x1b\x6f\xf9\x99\x52\x37\x18\xd7\x75\x59\x28\xf1\xf3\x2c\x49\xf6\xa8\xee\x9d\xbf\xc1\x19\xdd\x67\x7a\x96\x66\xb4\x5f\x5c\x4a\x3b\xc7\x74\xce\x78\x97\x5c\xc9\xc6\xb4\xb7\x7d\xe5\x84\x4e\x77\xc2\x56\xed\x96\xe5\x6a\xbf\x2e\xc3\x18\x22\x64\xde\x6e\xb9\x55\xda\xd5\xfb\x6c\x91\x65\x59\x70\x84\x90\xc2\x42\xd9\xca\xdc\x35\x24\x8d\xbc\x30\xc0\xeb\x3a\x02\x54\xa0\xc9\xb5\x68\xac\xd2\xa1\x89\x06\x1c\x88\xdd\x0d\x2d\xf3\x02\x4b\xde\xd6\x16\x1e\x79\xdd\xa2\x59\xd2\xaf\x28\xb8\x63\x50\xda\xf7\xdc\x85\xeb\x8a\xde\xd7\x68\x40\x58\xe2\x26\xc4\x2b\x14\xba\xef\xd7\x8f\x5c\x0b\xbe\xad\xd1\xb0\x8c\xf4\x71\x9a\xcd\x17\x70\xc8\x5e\x42\x89\xce\x66\xa1\x1c\x8c\x61\x09\x67\xc1\x8e\x9b\x0d\x6c\xb9\xc1\xb3\xee\x21\xba\xd3\x1a\x96\x4d\x26\x8d\xff\xbe\xd9\xb8\x38\x34\x91\x83\x79\x0f\x7c\xe2\x7b\x97\x43\x1d\xf3\x3c\xf3\x85\x2b\xd8\xd0\x68\x21\xad\x57\x6a\xca\x5c\x09\xa3\x58\xb9\xbf\xfa\x0e\x1b\x07\xf4\x5c\xe2\x93\x75\x5d\xf9\x63\x6b\x09\xa8\x45\xba\x80\x03\x35\x08\x8d\xb6\xd5\x72\xd8\xc7\x0f\xc4\xe8\xb8\x73\xfb\x04\xb9\x92\x16\x9f\x2c\xd9\x42\xbf\x4b\xd8\x0f\xa4\x42\xc9\x05\xcc\x69\xf9\x8d\x3c\xb2\x04\xd4\x9a\xee\x70\x72\x27\xa2\xa4\x35\x99\xe4\x8d\x63\xef\x1f\x79\xfd\xab\x16\x16\x49\xf0\x12\xf6\x8b\xbf\x39\x82\x3f\x6d\x40\x8a\x3a\x30\x45\x75\xa4\xa8\x9d\x38\xb7\xe9\x1a\x59\x7f\x42\xda\x78\x4d\xa3\x1c\x3a\xee\xe8\x6f\x37\x0a\xfa\x04\xed\xa4\x8b\x9c\x22\xd7\x03\xf7\x73\xf8\x1d\xa9\x43\x9f\xe6\x29\xb1\x84\x8a\x78\x7c\xc4\x5c\x94\xea\x2c\xbb\xec\x2d\x71\xb6\xaf\xfd\xe5\xba\xaf\x28\xe4\xcd\xea\xa2\x75\x34\x85\x38\xd6\x77\x21\x3b\xfc\xea\xdb\x90\x1b\x47\x23\x82\x64\x1f\xc5\x13\x16\xb7\xf2\x57\x61\xab\xc0\xf4\x4f\xdd\xd3\x87\xb9\x81\x2c\xf7\x2d\xe9\xa3\x78\x12\xf2\xe7\xd0\x38\x32\x07\xcd\x31\xaf\x6b\x95\xae\x9f\xdf\x33\xc6\xbe\xdf\x7f\xa7\x88\x71\x9b\xde\xe7\x49\xd2\x89\x25\xcc\x7e\x23\xca\xa7\x98\x85\xe4\x3a\xaf\x81\xd7\xeb\x44\xfa\x3d\xad\x05\xc1\xe4\x65\x9a\xf9\x62\xd9\x8b\xed\x27\xa4\x49\x77\x79\x66\x92\x81\xf1\xc4\xf2\x41\xf1\x97\x4d\x8f\xf7\x9e\xbb\x22\x31\xac\x0c\x23\xcd\xd1\x6d\x2b\x98\x51\xe9\x73\x89\x92\x44\xc8\x3b\x34\xf9\x14\x66\x25\xbb\xb3\xba\xcd\xad\x9f\x37\x06\x9e\xf5\x2b\x40\xd9\xee\x61\x5c\x13\x43\x97\x29\x40\x22\xd7\xa1\xe8\x15\x98\xd7\x5c\xbb\x6c\x35\x30\xa7\xe7\x4b\xd2\x7d\x16\x2c\x34\xde\x49\x12\x4f\x73\xaa\xa1\xb3\x92\xc5\x88\x9a\xbb\x7e\x5c\xb2\x5b\xf3\x5e\xb6\xfb\xc5\x82\xbe\xbf\x36\x05\xb7\xd8\xc7\x5c\xc9\x8e\x03\xae\x17\x38\x2b\xd9\x67\x65\x04\xdd\x1f\x23\x2f\x52\xac\xd7\x0e\x59\x67\x7e\xd7\x51\x4b\x1e\x1e\x80\x49\x3f\x70\x8f\x17\x22\x2c\x23\xe8\x50\x12\x1c\x2c\x8b\xf1\x10\x25\x04\x57\x9d\x04\xdf\xbd\xe7\x4e\xf5\x10\xf2\x56\x16\xf8\x44\x81\x73\x7c\xda\x1f\xb0\x77\xbd\x0e\x31\xb2\x57\xc9\x80\xf1\xbf\x36\xe0\xbc\xee\x3f\xd1\x2e\x0d\xbe\xd1\x42\x94\xf0\xb2\x5f\xc7\x11\xe9\x49\x8e\x82\x92\x4d\x13\xfe\x60\x4a\x96\xe2\xe0\xb9\xba\x6e\x78\xaa\x8f\x23\x14\x94\x84\x5c\x23\xef\xdf\xa4\x44\x71\x09\x99\x23\x91\x9b\x14\xeb\xa8\x04\x9b\x0f\x8f\x31\xb2\xe4\x8b\xd8\xa3\xff\xfa\xfa\xf5\xf6\x1d\x74\x9d\xeb\x64\x8b\xe1\x71\xe7\x2f\xfb\x42\x39\xd0\x75\x67\x53\xd6\xc7\xec\x38\xc0\xff\x53\x68\x46\x5c\x7f\x14\xa0\xd6\x09\xf9\xef\xe0\x19\x29\x12\x41\x1a\x10\xfa\x23\xb8\xf8\x6a\x79\x26\xd3\x1d\x2c\x92\xf4\x3b\x8b\xc9\x69\x6b\x59\xc1\xcc\x15\x21\x9a\xa4\x1c\x7d\x09\x53\x37\x88\xcd\xff\x6c\x16\x7e\x8a\x98\x26\xda\x24\x00\xca\x80\x82\x30\xc0\x87\xf9\xaf\x87\x6a\x3a\xc2\x6a\x1a\xc0\x82\x5b\xf7\x2f\x95\x9c\xd7\x54\x1a\xb7\xcf\x8e\x74\xdb\x8a\xba\xa0\x79\x7c\x8b\xa5\xd2\x08\x86\x3f\x22\x4b\xea\x20\x3d\xe1\x46\xb6\x5e\x0f\x75\x6d\xd0\x63\x0c\xfa\x40\x7d\x7f\xf5\xdd\x81\xee\xed\xf4\x80\x9e\x54\x8f\xb1\xa0\xc1\x21\x91\x29\xce\x44\xc9\x9c\x7b\x73\xe9\x42\x4f\x59\xca\xa1\xcf\x3a\x79\x63\xaf\x7a\x68\xa3\xd8\xb4\x3f\xfd\xbe\x0c\x13\x6f\x6c\xbc\xe7\x0a\xfa\x48\x15\x57\x96\x7e\x77\x75\x68\x7e\xf1\xaa\xd0\x8a\x8f\x9b\x71\x1c\xe9\xe2\x4c\x97\xf0\xff\xdd\xbb\x25\xb6\x3b\x78\xd1\x00\x72\xfb\x6f\x4b\x28\xe5\x30\x85\x11\x02\xf1\x38\x19\x41\x4b\x79\x5e\xfe\xd9\x19\x34\x99\x8a\xc3\x04\x3a\x68\xdc\xff\x0e\x83\x6a\x6a\x51\xf7\x93\x4a\x9c\x7c\x9f\xff\xf4\xff\x12\x08\x8b\x7f\x07\x00\x00\xff\xff\xfa\xfb\xab\xcc\xf7\x15\x00\x00") + +func templateRuntimeTmplBytes() ([]byte, error) { + return bindataRead( + _templateRuntimeTmpl, + "template/runtime.tmpl", + ) +} + +func templateRuntimeTmpl() (*asset, error) { + bytes, err := templateRuntimeTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "template/runtime.tmpl", size: 5623, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templateTxTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x4d\x8f\xdb\x36\x10\x3d\x4b\xbf\x62\x6a\x2c\x02\x7b\xe1\xa5\xd2\xdc\xba\xc0\x1e\x82\x4d\x0a\x04\x28\x16\x68\xe3\xa2\xb9\x25\x34\x39\xb6\x88\xc8\xa4\x4b\x8d\xbc\x32\x04\xff\xf7\x62\x48\xea\xc3\x6b\xa7\x69\x8b\x5e\xb2\x16\x39\x1f\x6f\x86\x6f\x1e\x99\xae\x2b\x6e\xf3\x47\xb7\x3f\x7a\xb3\x2d\x09\xde\xbc\xfe\xf1\xa7\xbb\xbd\xc7\x1a\x2d\xc1\xcf\x52\xe1\xda\xb9\xaf\xf0\xc1\x2a\x01\x6f\xab\x0a\x82\x51\x0d\xbc\xef\x0f\xa8\x45\xbe\x2a\x4d\x0d\xb5\x6b\xbc\x42\x50\x4e\x23\x98\x1a\x2a\xa3\xd0\xd6\xa8\xa1\xb1\x1a\x3d\x50\x89\xf0\x76\x2f\x55\x89\xf0\x46\xbc\xee\x77\x61\xe3\x1a\xab\x73\x63\xc3\xfe\x2f\x1f\x1e\xdf\x3f\x7d\x7c\x0f\x1b\x53\x21\xa4\x35\xef\x1c\x81\x36\x1e\x15\x39\x7f\x04\xb7\x01\x9a\x24\x23\x8f\x28\xf2\xdb\xe2\x74\xca\xf3\xae\x03\x8d\x1b\x63\x11\x66\xd4\xce\x20\x2d\x11\xee\xf6\x95\x24\x84\x59\x89\x52\xa3\x9f\xc1\x4d\xd8\x32\xbb\xbd\xf3\x04\xf3\x3c\x9b\x29\x67\x09\x5b\x9a\xe5\xd9\xac\x3e\x5a\x35\xcb\xf3\x6c\xb6\x35\x54\x36\x6b\xa1\xdc\xae\xd8\xa4\xfa\x8d\x55\xcd\x5a\x92\xf3\x05\x5a\x2a\xb4\x91\x15\x2a\x9a\xe5\x8b\x3c\x2f\x0a\x58\xb5\x5c\xb3\x04\xf2\xd2\xd6\x52\x91\x71\x56\x56\xa0\x2a\xc3\x1d\xa4\x52\x12\x6f\x2b\x8f\x92\x50\xc3\xfa\x08\x4a\x56\x95\xb1\x5b\x78\x0c\x16\x62\xd5\xce\x17\x22\xa7\xe3\x1e\x39\x52\x4d\xbe\x51\x04\x5d\x9e\x29\x67\x37\x66\x9b\x67\x5d\x07\x5e\xda\x2d\xc2\xcd\xe7\x25\xdc\x58\xb8\x7f\x80\x1b\xf1\xe4\x34\xd6\x70\x77\x3a\xe5\x59\x56\x14\xd0\x75\x70\x63\xc5\x93\xdc\x21\x9c\x4e\x9c\x8e\xdb\x97\x10\x6c\x9c\x07\x63\x09\x3d\x43\xb3\x5b\x78\x36\x54\x86\xfd\x73\xa7\x75\x63\x2a\x8d\xbe\x16\x79\x96\x9d\xef\xdc\x9e\x7d\x46\xd4\x01\x16\x5a\xcd\xfd\x3c\x85\x2e\x3c\xba\xdd\xce\x10\xa8\xf0\x27\x02\x98\x34\x44\xe4\x9b\xc6\x2a\x98\x53\x0b\xb7\xab\x76\x91\xac\xe7\x0b\x40\xef\x9d\xe7\x72\x3d\x52\xe3\x2d\x50\x2b\x62\xe1\x42\x7b\x73\x40\x2f\xe6\xb7\xd4\xbe\x0b\x3f\x17\x82\x5a\xd1\x3b\xa6\xac\xbf\xb9\xaa\x5a\x4b\xf5\x15\x7c\xfa\xf1\xdd\xcc\xbd\xc7\x7f\xc8\x3d\xba\xf6\x35\xc7\x0e\x47\x77\xa6\xc0\xe3\xe4\xd0\xd7\xc6\xea\x1a\xc8\x81\x6a\xbc\x0f\xab\x7f\xd3\x8e\xe0\x37\x5f\xc0\x6d\x8a\xc0\xe7\x1f\x7f\xdd\x3f\xc0\xab\xb8\xd8\x45\x70\xf7\x23\xce\x53\x6f\x25\x8c\x0d\x4d\xe9\x2b\x89\xab\x8c\xf2\x3c\x4f\x34\xe3\xe8\xdf\x61\x15\x00\x40\x46\xad\x38\x67\xc2\x03\x3c\xe1\xf3\x15\x36\xcc\x07\x44\x8b\x81\x18\x77\x91\x19\xac\x2e\xb0\x31\xbe\x26\xb0\xac\x0e\xcc\x46\xed\x14\x60\x2b\x77\xfb\x0a\x21\xcc\x6f\xd7\xdd\xc1\x4d\x34\xba\x7f\x00\x63\x35\xb6\x03\x9a\xd7\x61\x64\x8b\x02\xfa\xa3\x80\x67\x2f\xf7\xf1\x98\xb7\xe6\x80\x16\xd2\x38\x8a\x55\x1b\xb9\x2d\xc1\xba\xfd\xb0\x9a\x9c\x0c\x67\xdb\xa1\x25\x19\xfb\xcf\x73\x5b\x22\x18\x8d\x32\xcc\x8b\x83\xba\xd9\x07\x59\x98\x1c\x53\x1d\x02\xba\x86\x40\x6a\xcd\xb3\x23\xed\x11\xb0\x25\x2f\xa3\xd4\x91\x0b\x30\xc6\xd1\x29\x0a\xf8\xa3\x44\x0b\xb2\x5f\x0b\xc3\x1e\xc2\x27\x4a\xf1\xb4\x2f\xc1\x10\x6c\x31\x4d\x49\xcd\x9d\x9c\xd4\x60\x6c\x4d\xd2\x2a\x14\x93\xa9\x92\x56\x8f\x54\x97\x1e\x43\x85\xdc\x4a\x0e\x10\x86\x9b\x25\xa7\xc7\x11\xcc\x79\xa7\xa9\xd1\xc3\xae\xa9\x29\xc0\x00\x67\x91\x63\x06\x1d\xc5\x1d\xab\xac\xf3\x41\x9f\x5d\x1a\x5b\x70\x7e\x18\xa4\xcb\x39\x2a\x0a\xf6\xfe\xb0\x01\x09\xaa\x72\x2c\xef\x93\x6d\x6e\x22\xee\xd6\xa8\x35\xea\x10\xd9\x62\x4a\x04\x5b\xb4\xe8\x83\xf8\xa1\x25\x43\x06\xeb\xe5\x80\x30\xac\x1c\x39\xae\xdc\xef\x2b\x83\x3c\x44\x7f\x36\xe8\x8f\xcb\x50\x5e\x62\xc9\x7d\xd0\xaa\x40\x90\x9e\x78\xe2\x57\xb6\xfa\xf4\xe9\x13\xb7\x93\x23\x05\x2f\x78\x36\x55\x05\x6b\x04\x6c\x51\x35\x84\x3a\x10\xa7\xf4\xae\xd9\x46\xcd\xd3\x89\x42\xa5\x51\xe5\xa0\xc9\xe1\x56\xb9\x52\xea\x93\x23\x8c\xb3\x3c\x70\xcf\xd4\x60\x1d\xc1\xd6\x79\xd7\x10\xdf\x37\xb5\xdc\x60\x52\xef\xc1\x68\xd4\xf0\x90\x7d\xcc\x8a\x50\x93\xf4\x31\xe5\x59\x73\x61\xe3\xdd\x4e\xe4\x99\xf6\x87\x17\xc4\x8d\x31\xda\x5e\xd3\xc3\x85\x5a\x1d\x99\x8b\x67\x80\x33\x6a\x27\x1c\x4a\xf2\x64\xf1\x79\xd5\xa6\x2a\xb9\xb1\x16\x9f\x5f\x5c\x52\x89\x94\x51\x25\x82\xf9\x5c\x51\x0b\xe9\x56\x14\x8f\xf1\xef\x12\x2e\x71\x2d\x60\x14\xc7\x65\x54\xd2\xa0\x2b\xd4\x86\x2f\x9e\x63\xed\x0f\x22\x06\x5c\xe4\x99\xd9\x84\xe5\x1f\x1e\xc0\x9a\x8a\x0d\x7b\xa9\xb2\xa6\x0a\x1e\x79\x76\x1a\xe4\xeb\x55\x1f\xb9\xa3\x96\xe5\x2e\x00\xb8\xe7\x7f\x4e\x4b\x76\x48\xf5\xad\xda\x41\x7a\x5f\xf6\x93\x35\x62\x8f\x9e\x95\xaf\xc7\x4b\x0e\xe4\xc1\x19\xdd\xcf\x94\xf3\xe3\x48\x85\x29\xe5\x90\x7c\x0e\xd7\x87\x4a\xc0\xc7\xd2\x35\x95\x66\x76\xb1\x39\x6a\x70\xb6\x3a\xf2\x85\x7e\xdd\x7e\x22\xbd\x23\x08\xee\xc7\x79\x73\x17\x30\x1f\x0f\x6e\xec\x24\x0c\x77\x52\xa8\x18\x62\xc5\xef\xa2\xe5\x59\xd9\xc9\xbb\x9f\xb6\x7f\xca\xb5\x6b\xe8\x52\xf8\xf9\x82\x29\xcc\x1c\x9b\xc0\x10\x7c\x9c\xa3\x41\x7f\x01\xba\x1a\xe3\xeb\x87\x15\x29\xc8\x42\x1f\x7a\x12\x37\x98\x8d\x17\x2e\x8c\x47\x0f\x67\x8f\x87\x31\x50\xfc\xfe\xa6\xc2\x05\x6d\xfc\xfd\x5c\xdd\xbe\xac\xfa\xd7\xc1\x97\x6b\xd2\xf6\x8d\x67\xc1\x14\xe5\x8b\x37\xc9\x25\xcc\x81\x2f\x03\xd0\x41\x2d\xff\x35\xd4\x3e\xd6\x39\xd8\x6f\xab\xef\x05\xdc\xcb\x87\xcc\x25\xe0\xf7\x2d\xaa\xfe\x0a\x6a\x05\x7f\x5d\x3f\x78\xde\xb9\x3e\xf9\x51\x56\x23\x1d\x96\x20\xfd\xb6\x5e\xc2\x21\x56\xc9\x8f\xe3\xee\x74\xf5\x19\x95\x92\x71\xc8\x65\xaf\xe7\xc9\xb7\x7f\x3b\x05\xfd\x1e\xb1\x85\xcf\xeb\xe0\xc2\xd6\xff\x8c\x6e\x88\x79\x15\xde\x41\x7a\xf8\xfc\xf2\x05\xf1\x30\xed\xfe\xdc\x9a\x6a\x11\xfe\x93\x91\x1e\xc1\x7f\x05\x00\x00\xff\xff\x73\xc6\x54\xa9\x46\x0d\x00\x00") func templateTxTmplBytes() ([]byte, error) { return bindataRead( @@ -975,7 +1059,7 @@ func templateTxTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/tx.tmpl", size: 3425, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/tx.tmpl", size: 3398, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1055,6 +1139,7 @@ var _bindata = map[string]func() (*asset, error){ "template/base.tmpl": templateBaseTmpl, "template/builder/create.tmpl": templateBuilderCreateTmpl, "template/builder/delete.tmpl": templateBuilderDeleteTmpl, + "template/builder/mutation.tmpl": templateBuilderMutationTmpl, "template/builder/query.tmpl": templateBuilderQueryTmpl, "template/builder/setter.tmpl": templateBuilderSetterTmpl, "template/builder/update.tmpl": templateBuilderUpdateTmpl, @@ -1089,11 +1174,14 @@ var _bindata = map[string]func() (*asset, error){ "template/dialect/sql/update.tmpl": templateDialectSqlUpdateTmpl, "template/ent.tmpl": templateEntTmpl, "template/header.tmpl": templateHeaderTmpl, + "template/hook.tmpl": templateHookTmpl, "template/import.tmpl": templateImportTmpl, "template/meta.tmpl": templateMetaTmpl, "template/migrate/migrate.tmpl": templateMigrateMigrateTmpl, "template/migrate/schema.tmpl": templateMigrateSchemaTmpl, "template/predicate.tmpl": templatePredicateTmpl, + "template/privacy.tmpl": templatePrivacyTmpl, + "template/runtime.tmpl": templateRuntimeTmpl, "template/tx.tmpl": templateTxTmpl, "template/where.tmpl": templateWhereTmpl, } @@ -1142,11 +1230,12 @@ var _bintree = &bintree{nil, map[string]*bintree{ "template": &bintree{nil, map[string]*bintree{ "base.tmpl": &bintree{templateBaseTmpl, map[string]*bintree{}}, "builder": &bintree{nil, map[string]*bintree{ - "create.tmpl": &bintree{templateBuilderCreateTmpl, map[string]*bintree{}}, - "delete.tmpl": &bintree{templateBuilderDeleteTmpl, map[string]*bintree{}}, - "query.tmpl": &bintree{templateBuilderQueryTmpl, map[string]*bintree{}}, - "setter.tmpl": &bintree{templateBuilderSetterTmpl, map[string]*bintree{}}, - "update.tmpl": &bintree{templateBuilderUpdateTmpl, map[string]*bintree{}}, + "create.tmpl": &bintree{templateBuilderCreateTmpl, map[string]*bintree{}}, + "delete.tmpl": &bintree{templateBuilderDeleteTmpl, map[string]*bintree{}}, + "mutation.tmpl": &bintree{templateBuilderMutationTmpl, map[string]*bintree{}}, + "query.tmpl": &bintree{templateBuilderQueryTmpl, map[string]*bintree{}}, + "setter.tmpl": &bintree{templateBuilderSetterTmpl, map[string]*bintree{}}, + "update.tmpl": &bintree{templateBuilderUpdateTmpl, map[string]*bintree{}}, }}, "client.tmpl": &bintree{templateClientTmpl, map[string]*bintree{}}, "config.tmpl": &bintree{templateConfigTmpl, map[string]*bintree{}}, @@ -1185,6 +1274,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ }}, "ent.tmpl": &bintree{templateEntTmpl, map[string]*bintree{}}, "header.tmpl": &bintree{templateHeaderTmpl, map[string]*bintree{}}, + "hook.tmpl": &bintree{templateHookTmpl, map[string]*bintree{}}, "import.tmpl": &bintree{templateImportTmpl, map[string]*bintree{}}, "meta.tmpl": &bintree{templateMetaTmpl, map[string]*bintree{}}, "migrate": &bintree{nil, map[string]*bintree{ @@ -1192,6 +1282,8 @@ var _bintree = &bintree{nil, map[string]*bintree{ "schema.tmpl": &bintree{templateMigrateSchemaTmpl, map[string]*bintree{}}, }}, "predicate.tmpl": &bintree{templatePredicateTmpl, map[string]*bintree{}}, + "privacy.tmpl": &bintree{templatePrivacyTmpl, map[string]*bintree{}}, + "runtime.tmpl": &bintree{templateRuntimeTmpl, map[string]*bintree{}}, "tx.tmpl": &bintree{templateTxTmpl, map[string]*bintree{}}, "where.tmpl": &bintree{templateWhereTmpl, map[string]*bintree{}}, }}, diff --git a/entc/gen/template.go b/entc/gen/template.go index 6875d627a..8a924276b 100644 --- a/entc/gen/template.go +++ b/entc/gen/template.go @@ -29,8 +29,8 @@ type ( // the Graph object. GraphTemplate struct { Name string // template name. - Format string // file name format. Skip func(*Graph) bool // skip condition. + Format string // file name format. } ) @@ -90,6 +90,10 @@ var ( Name: "config", Format: "config.go", }, + { + Name: "mutation", + Format: "mutation.go", + }, { Name: "migrate", Format: "migrate/migrate.go", @@ -104,6 +108,22 @@ var ( Name: "predicate", Format: "predicate/predicate.go", }, + { + Name: "hook", + Format: "hook/hook.go", + }, + { + Name: "privacy", + Format: "privacy/privacy.go", + }, + { + Name: "runtime/ent", + Format: "runtime.go", + }, + { + Name: "runtime/pkg", + Format: "runtime/runtime.go", + }, } // templates holds the Go templates for the code generation. // the init function below initializes the templates and its diff --git a/entc/gen/template/base.tmpl b/entc/gen/template/base.tmpl index 184426bb8..280ad2f6d 100644 --- a/entc/gen/template/base.tmpl +++ b/entc/gen/template/base.tmpl @@ -11,6 +11,16 @@ in the LICENSE file in the root directory of this source tree. {{ template "import" $ }} +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func({{ $.Storage.Builder }}) diff --git a/entc/gen/template/builder/create.tmpl b/entc/gen/template/builder/create.tmpl index ce5be8c72..041467f2f 100644 --- a/entc/gen/template/builder/create.tmpl +++ b/entc/gen/template/builder/create.tmpl @@ -11,21 +11,20 @@ in the LICENSE file in the root directory of this source tree. {{ template "import" $ }} +import ( + {{- range $path := $.SiblingImports }} + "{{ $path }}" + {{- end }} +) + {{ $builder := print (pascal $.Name) "Create" }} {{ $receiver := receiver $builder }} // {{ $builder }} is the builder for creating a {{ $.Name }} entity. type {{ $builder }} struct { config - {{- if $.ID.UserDefined }} - {{ $.ID.BuilderField }} *{{ $.ID.Type }} - {{- end }} - {{ range $_, $f := $.Fields }} - {{- $f.BuilderField }} *{{ $f.Type }} - {{ end }} - {{- range $_, $e := $.Edges }} - {{- $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{} - {{ end -}} + mutation *{{ $.MutationName }} + hooks []Hook } {{ with extend $ "Builder" $builder }} @@ -34,40 +33,61 @@ type {{ $builder }} struct { // Save creates the {{ $.Name }} in the database. func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (*{{ $.Name }}, error) { - {{ range $_, $f := $.Fields -}} - {{- if or $f.Default (not $f.Optional) -}} - if {{ $receiver }}.{{ $f.BuilderField }} == nil { - {{ if $f.Default -}} + {{- $mutation := print $receiver ".mutation" }} + {{- range $_, $f := $.Fields }} + {{- if or $f.Default (not $f.Optional) }} + if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok { + {{- if $f.Default }} v := {{ $.Package }}.{{ $f.DefaultName }}{{ if or $f.IsTime $f.IsUUID }}(){{ end }} - {{ $receiver }}.{{ $f.BuilderField }} = &v - {{ else -}} + {{ $mutation }}.Set{{ $f.StructField }}(v) + {{- else }} return nil, errors.New("{{ $pkg }}: missing required field \"{{ $f.Name }}\"") - {{ end -}} + {{- end }} } - {{ end -}} - {{ with or $f.Validators $f.IsEnum -}} - {{/* add nullable check only for optional fields without default value */ -}} - {{ $nullable := and $f.Optional (not $f.Default) -}} - {{- if $nullable }} if {{ $receiver }}.{{ $f.BuilderField }} != nil { {{ end -}} - if err := {{ $.Package }}.{{ $f.Validator }}(*{{ $receiver }}.{{ $f.BuilderField }}); err != nil { + {{- end }} + {{- with or $f.Validators $f.IsEnum }} + if v, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { + if err := {{ $.Package }}.{{ $f.Validator }}(v); err != nil { return nil, fmt.Errorf("{{ $pkg }}: validator failed for field \"{{ $f.Name }}\": %v", err) } - {{- if $nullable }} } {{ end }} - {{ end -}} - {{ end -}} - {{- range $_, $e := $.Edges }} - {{- if $e.Unique -}} - if len({{ $receiver }}.{{ $e.BuilderField }}) > 1 { - return nil, errors.New("{{ $pkg }}: multiple assignments on a unique edge \"{{ $e.Name }}\"") } - {{ end -}} - {{- if not $e.Optional -}} - if {{ $receiver }}.{{ $e.BuilderField }} == nil { + {{- end }} + {{- end }} + {{- range $_, $e := $.Edges }} + {{- if not $e.Optional }} + {{- if $e.Unique }} + if _, ok := {{ $mutation }}.{{ $e.StructField }}ID(); !ok { + {{- else }} + if len({{ $mutation }}.{{ $e.StructField }}IDs()) == 0 { + {{- end }} return nil, errors.New("{{ $pkg }}: missing required edge \"{{ $e.Name }}\"") } - {{ end -}} - {{ end -}} - return {{ $receiver }}.{{ $.Storage }}Save(ctx) + {{- end }} + {{- end }} + var ( + err error + node *{{ $.Name }} + ) + if len({{ $receiver }}.hooks) == 0 { + node, err = {{ $receiver }}.{{ $.Storage }}Save(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*{{ $.MutationName }}) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + {{ $mutation }} = mutation + node, err = {{ $receiver }}.{{ $.Storage }}Save(ctx) + return node, err + }) + for i := len({{ $receiver }}.hooks); i > 0; i-- { + mut = {{ $receiver }}.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, {{ $mutation }}); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -84,4 +104,4 @@ func ({{ $receiver }} *{{ $builder }}) SaveX(ctx context.Context) *{{ $.Name }} {{ xtemplate $tmpl . }} {{ end }} -{{ end }} +{{ end }} \ No newline at end of file diff --git a/entc/gen/template/builder/delete.tmpl b/entc/gen/template/builder/delete.tmpl index 48ff29ee4..d6c3c97ca 100644 --- a/entc/gen/template/builder/delete.tmpl +++ b/entc/gen/template/builder/delete.tmpl @@ -11,24 +11,56 @@ in the LICENSE file in the root directory of this source tree. {{ template "import" $ }} +import ( + "{{ $.Config.Package }}/{{ $.Package }}" +) + + {{ $builder := print (pascal $.Name) "Delete" }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} + // {{ $builder }} is the builder for deleting a {{ pascal $.Name }} entity. type {{ $builder }} struct { config + hooks []Hook + mutation *{{ $.MutationName }} predicates []predicate.{{ $.Name }} } // Where adds a new predicate to the delete builder. -func ({{ $receiver}} *{{ $builder }}) Where(ps ...predicate.{{ $.Name }}) *{{ $builder }} { +func ({{ $receiver }} *{{ $builder }}) Where(ps ...predicate.{{ $.Name }}) *{{ $builder }} { {{ $receiver}}.predicates = append({{ $receiver}}.predicates, ps...) return {{ $receiver }} } // Exec executes the deletion query and returns how many vertices were deleted. func ({{ $receiver}} *{{ $builder }}) Exec(ctx context.Context) (int, error) { - return {{ $receiver }}.{{ $.Storage }}Exec(ctx) + var ( + err error + affected int + ) + if len({{ $receiver }}.hooks) == 0 { + affected, err = {{ $receiver }}.{{ $.Storage }}Exec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*{{ $.MutationName }}) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + {{ $mutation }} = mutation + affected, err = {{ $receiver }}.{{ $.Storage }}Exec(ctx) + return affected, err + }) + for i := len({{ $receiver }}.hooks); i > 0; i-- { + mut = {{ $receiver }}.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, {{ $mutation }}); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/gen/template/builder/mutation.tmpl b/entc/gen/template/builder/mutation.tmpl new file mode 100644 index 000000000..c4f46cbec --- /dev/null +++ b/entc/gen/template/builder/mutation.tmpl @@ -0,0 +1,587 @@ +{{/* +Copyright 2019-present Facebook Inc. All rights reserved. +This source code is licensed under the Apache 2.0 license found +in the LICENSE file in the root directory of this source tree. +*/}} + +{{ define "mutation" }} + +{{ $pkg := base $.Config.Package }} +{{ template "header" $ }} + +import ( + {{- range $n := $.Nodes }} + "{{ $.Config.Package }}/{{ $n.Package }}" + {{- end }} +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + {{- range $n := $.Nodes }} + Type{{ $n.Name }} = "{{ $n.Name }}" + {{- end }} +) + +{{ range $n := $.Nodes }} + +{{ $mutation := $n.MutationName }} +// {{ $mutation }} represents an operation that mutate the {{ plural $n.Name }} +// nodes in the graph. +type {{ $mutation }} struct { + config + op Op + typ string + {{ $n.ID.BuilderField }} *{{ $n.ID.Type }} + {{- range $f := $n.Fields }} + {{ $f.BuilderField }} *{{ $f.Type }} + {{- if $f.Type.Numeric }} + add{{ $f.BuilderField }} *{{ $f.Type }} + {{- end }} + {{- end }} + clearedFields map[string]bool + {{- range $e := $n.Edges }} + {{- if $e.Unique }} + {{ $e.BuilderField }} *{{ $e.Type.ID.Type }} + cleared{{ $e.BuilderField }} bool + {{- else }} + {{ $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{} + removed{{ $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{} + {{- end }} + {{- end }} +} + +var _ ent.Mutation = (*{{ $mutation }})(nil) + +// new{{ $mutation }} creates new mutation for $n.Name. +func new{{ $mutation }}(c config, op Op) *{{ $mutation }} { + return &{{ $mutation }}{ + config: c, + op: op, + typ: Type{{ $n.Name }}, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m {{ $mutation }}) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m {{ $mutation }}) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("{{ $pkg }}: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +{{- if $n.ID.UserDefined }} + // SetID sets the value of the id field. Note that, this + // operation is accepted only on {{ $n.Name }} creation. + func (m *{{ $mutation }}) SetID(id {{ $n.ID.Type }}) { + m.{{ $n.ID.BuilderField }} = &id + } +{{- end }} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *{{ $mutation }}) ID() (id {{ $n.ID.Type }}, exists bool) { + if m.{{ $n.ID.BuilderField }} == nil { + return + } + return *m.{{ $n.ID.BuilderField }}, true +} + +{{ range $f := $n.Fields }} + {{ $p := receiver $f.Type.String }} + {{ $func := print "Set" $f.StructField }} + {{ $const := print $n.Package "." $f.Constant }} + // {{ $func }} sets the {{ $f.Name }} field. + func (m *{{ $mutation }}) {{ $func }}({{ $p }} {{ $f.Type }}) { + m.{{ $f.BuilderField }} = &{{ $p }} + {{- /* setting numeric type override previous calls to Add. */}} + {{- if $f.Type.Numeric }} + m.add{{ $f.BuilderField }} = nil + {{- end }} + } + + // {{ $f.MutationGet }} returns the {{ $f.Name }} value in the mutation. + func (m *{{ $mutation }}) {{ $f.MutationGet }}() (r {{ $f.Type }}, exists bool) { + v := m.{{ $f.BuilderField }} + if v == nil { + return + } + return *v, true + } + + {{ if and $f.Type.Numeric }} + {{ $func := print "Add" $f.StructField }} + // {{ $func }} adds {{ $p }} to {{ $f.Name }}. + func (m *{{ $mutation }}) {{ $func }}({{ $p }} {{ $f.Type }}) { + if m.add{{ $f.BuilderField }} != nil { + *m.add{{ $f.BuilderField }} += {{ $p }} + } else { + m.add{{ $f.BuilderField }} = &{{ $p }} + } + } + + // Added{{ $f.StructField }} returns the value that was added to the {{ $f.Name }} field in this mutation. + func (m *{{ $mutation }}) Added{{ $f.StructField }}() (r {{ $f.Type }}, exists bool) { + v := m.add{{ $f.BuilderField }} + if v == nil { + return + } + return *v, true + } + {{ end }} + + {{ if $f.Optional }} + {{ $func := print "Clear" $f.StructField }} + // {{ $func }} clears the value of {{ $f.Name }}. + func (m *{{ $mutation }}) {{ $func }}() { + m.{{ $f.BuilderField }} = nil + {{- if $f.Type.Numeric }} + m.add{{ $f.BuilderField }} = nil + {{- end }} + m.clearedFields[{{ $const }}] = true + } + + {{ $func = print $f.StructField "Cleared" }} + // {{ $func }} returns if the field {{ $f.Name }} was cleared in this mutation. + func (m *{{ $mutation }}) {{ $func }}() bool { + return m.clearedFields[{{ $const }}] + } + {{ end }} + + {{ $func = print "Reset" $f.StructField }} + // {{ $func }} reset all changes of the {{ $f.Name }} field. + func (m *{{ $mutation }}) {{ $func }}() { + m.{{ $f.BuilderField }} = nil + {{- if $f.Type.Numeric }} + m.add{{ $f.BuilderField }} = nil + {{- end }} + {{- if $f.Optional }} + delete(m.clearedFields, {{ $const }}) + {{- end }} + } +{{ end }} + + +{{ range $e := $n.Edges }} + {{ $op := "add" }}{{ if $e.Unique }}{{ $op = "set" }}{{ end }} + {{ $idsFunc := print (pascal $op) (singular $e.Name | pascal) "IDs" }}{{ if $e.Unique }}{{ $idsFunc = print (pascal $op) (pascal $e.Name) "ID" }}{{ end }} + // {{ $idsFunc }} {{ $op }}s the {{ $e.Name }} edge to {{ $e.Type.Name }} by id{{ if not $e.Unique }}s{{ end }}. + func (m *{{ $mutation }}) {{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }} {{ $e.Type.ID.Type }}) { + {{- if $e.Unique }} + m.{{ $e.BuilderField }} = &id + {{- else }} + if m.{{ $e.BuilderField }} == nil { + m.{{ $e.BuilderField }} = make(map[{{ $e.Type.ID.Type }}]struct{}) + } + for i := range ids { + m.{{ $e.BuilderField }}[ids[i]] = struct{}{} + } + {{- end }} + } + {{ if $e.Unique }} + {{ $func := print "Clear" $e.StructField }} + // {{ $func }} clears the {{ $e.Name }} edge to {{ $e.Type.Name }}. + func (m *{{ $mutation }}) {{ $func }}() { + m.cleared{{ $e.BuilderField }} = true + } + + {{ $func = print $e.StructField "Cleared" }} + // {{ $func }} returns if the edge {{ $e.Name }} was cleared. + func (m *{{ $mutation }}) {{ $func }}() bool { + return m.cleared{{ $e.BuilderField }} + } + + // {{ $e.StructField }}ID returns the {{ $e.Name }} id in the mutation. + func (m *{{ $mutation }}) {{ $e.StructField }}ID() (id {{ $e.Type.ID.Type }}, exists bool) { + if m.{{ $e.BuilderField }} != nil { + return *m.{{ $e.BuilderField }}, true + } + return + } + {{ else }} + {{ $p := lower (printf "%.1s" $e.Type.Name) }} + {{ $idsFunc := print "Remove" (singular $e.Name | pascal) "IDs" }} + // {{ $idsFunc }} removes the {{ $e.Name }} edge to {{ $e.Type.Name }} by ids. + func (m *{{ $mutation }}) {{ $idsFunc }}(ids ...{{ $e.Type.ID.Type }}) { + if m.removed{{ $e.BuilderField }} == nil { + m.removed{{ $e.BuilderField }} = make(map[{{ $e.Type.ID.Type }}]struct{}) + } + {{- if $e.Unique }} + m.removed{{ $e.BuilderField }}[id] = struct{}{} + {{- else }} + for i := range ids { + m.removed{{ $e.BuilderField }}[ids[i]] = struct{}{} + } + {{- end }} + } + + {{ $func := print "Removed" $e.StructField }} + // {{ $func }} returns the removed ids of {{ $e.Name }}. + func (m *{{ $mutation }}) {{ $func }}IDs() (ids []{{ $e.Type.ID.Type }}) { + for id := range m.removed{{ $e.BuilderField }} { + ids = append(ids, id) + } + return + } + {{ end }} + + // {{ $e.StructField }}IDs returns the {{ $e.Name }} ids in the mutation. + {{- if $e.Unique }} + // Note that ids always returns len(ids) <= 1 for unique edges, and you should use + // {{ $e.StructField }}ID instead. It exists only for internal usage by the builders. + {{- end }} + func (m *{{ $mutation }}) {{ $e.StructField }}IDs() (ids []{{ $e.Type.ID.Type }}) { + {{- if $e.Unique }} + if id := m.{{ $e.BuilderField }}; id != nil { + ids = append(ids, *id) + } + {{- else }} + for id := range m.{{ $e.BuilderField }} { + ids = append(ids, id) + } + {{- end}} + return + } + + + {{ $func := print "Reset" $e.StructField }} + // {{ $func }} reset all changes of the {{ $e.Name }} edge. + func (m *{{ $mutation }}) {{ $func }}() { + m.{{ $e.BuilderField }} = nil + {{- if $e.Unique }} + m.cleared{{ $e.BuilderField }} = false + {{- else }} + m.removed{{ $e.BuilderField }} = nil + {{- end }} + } +{{ end }} + + +// Op returns the operation name. +func (m *{{ $mutation }}) Op() Op { + return m.op +} + +// Type returns the node type of this mutation ({{ $n.Name }}). +func (m *{{ $mutation }}) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *{{ $mutation }}) Fields() []string { + fields := make([]string, 0, {{ len $n.Fields }}) + {{- range $f := $n.Fields }} + {{- $const := print $n.Package "." $f.Constant }} + if m.{{ $f.BuilderField }} != nil { + fields = append(fields, {{ $const }}) + } + {{- end }} + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *{{ $mutation }}) Field(name string) (ent.Value, bool) { + switch name { + {{- range $f := $n.Fields }} + {{- $const := print $n.Package "." $f.Constant }} + case {{ $const }}: + return m.{{ $f.MutationGet }}() + {{- end }} + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *{{ $mutation }}) SetField(name string, value ent.Value) error { + switch name { + {{- range $f := $n.Fields }} + {{- $const := print $n.Package "." $f.Constant }} + case {{ $const }}: + v, ok := value.({{ $f.Type }}) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.Set{{ $f.StructField }}(v) + return nil + {{- end }} + } + return fmt.Errorf("unknown {{ $n.Name }} field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *{{ $mutation }}) AddedFields() []string { + {{- if $n.HasNumeric }} + var fields []string + {{- range $f := $n.Fields }} + {{- if $f.Type.Numeric }} + {{- $const := print $n.Package "." $f.Constant }} + if m.add{{ $f.BuilderField }} != nil { + fields = append(fields, {{ $const }}) + } + {{- end }} + {{- end }} + return fields + {{- else }} + return nil + {{- end }} +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *{{ $mutation }}) AddedField(name string) (ent.Value, bool) { + {{- if $n.HasNumeric }} + switch name { + {{- range $f := $n.Fields }} + {{- if $f.Type.Numeric }} + {{- $const := print $n.Package "." $f.Constant }} + case {{ $const }}: + return m.Added{{ $f.StructField }}() + {{- end }} + {{- end }} + } + {{- end }} + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *{{ $mutation }}) AddField(name string, value ent.Value) error { + switch name { + {{- range $f := $n.Fields }} + {{- if $f.Type.Numeric }} + {{- $const := print $n.Package "." $f.Constant }} + case {{ $const }}: + v, ok := value.({{ $f.Type }}) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.Add{{ $f.StructField }}(v) + return nil + {{- end }} + {{- end }} + } + return fmt.Errorf("unknown {{ $n.Name }} numeric field %s", name) +} + + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *{{ $mutation }}) ClearedFields() []string { + {{- if $n.HasOptional }} + var fields []string + {{- range $f := $n.Fields }} + {{- if $f.Optional }} + {{- $const := print $n.Package "." $f.Constant }} + if m.clearedFields[{{ $const }}] { + fields = append(fields, {{ $const }}) + } + {{- end }} + {{- end }} + return fields + {{- else }} + return nil + {{- end }} +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *{{ $mutation }}) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *{{ $mutation }}) ClearField(name string) error { + {{- if $n.HasOptional }} + switch name { + {{- range $f := $n.Fields }} + {{- if $f.Optional }} + {{- $const := print $n.Package "." $f.Constant }} + case {{ $const }}: + m.Clear{{ $f.StructField }}() + return nil + {{- end }} + {{- end }} + } + {{- end }} + return fmt.Errorf("unknown {{ $n.Name }} nullable field %s", name) +} + + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *{{ $mutation }}) ResetField(name string) error { + switch name { + {{- range $f := $n.Fields }} + {{- $const := print $n.Package "." $f.Constant }} + case {{ $const }}: + m.Reset{{ $f.StructField }}() + return nil + {{- end }} + } + return fmt.Errorf("unknown {{ $n.Name }} field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *{{ $mutation }}) AddedEdges() []string { + edges := make([]string, 0, {{ len $n.Edges }}) + {{- range $e := $n.Edges }} + if m.{{ $e.BuilderField }} != nil { + {{- $const := print $n.Package "." $e.Constant }} + edges = append(edges, {{ $const }}) + } + {{- end }} + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *{{ $mutation }}) AddedIDs(name string) []ent.Value { + switch name { + {{- range $e := $n.Edges }} + {{- $const := print $n.Package "." $e.Constant }} + case {{ $const }}: + {{- if $e.Unique }} + if id := m.{{ $e.BuilderField }}; id != nil { + return []ent.Value{*id} + } + {{- else }} + ids := make([]ent.Value, 0, len(m.{{ $e.BuilderField }})) + for id := range m.{{ $e.BuilderField }} { + ids = append(ids, id) + } + return ids + {{- end }} + {{- end }} + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *{{ $mutation }}) RemovedEdges() []string { + edges := make([]string, 0, {{ len $n.Edges }}) + {{- range $e := $n.Edges }} + {{- if not $e.Unique }} + if m.removed{{ $e.BuilderField }} != nil { + {{- $const := print $n.Package "." $e.Constant }} + edges = append(edges, {{ $const }}) + } + {{- end }} + {{- end }} + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *{{ $mutation }}) RemovedIDs(name string) []ent.Value { + switch name { + {{- range $e := $n.Edges }} + {{- if not $e.Unique }} + {{- $const := print $n.Package "." $e.Constant }} + case {{ $const }}: + ids := make([]ent.Value, 0, len(m.removed{{ $e.BuilderField }})) + for id := range m.removed{{ $e.BuilderField }} { + ids = append(ids, id) + } + return ids + {{- end }} + {{- end }} + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *{{ $mutation }}) ClearedEdges() []string { + edges := make([]string, 0, {{ len $n.Edges }}) + {{- range $e := $n.Edges }} + {{- if $e.Unique }} + if m.cleared{{ $e.BuilderField }} { + {{- $const := print $n.Package "." $e.Constant }} + edges = append(edges, {{ $const }}) + } + {{- end }} + {{- end }} + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *{{ $mutation }}) EdgeCleared(name string) bool { + switch name { + {{- range $e := $n.Edges }} + {{- if $e.Unique }} + {{- $const := print $n.Package "." $e.Constant }} + case {{ $const }}: + return m.cleared{{ $e.BuilderField }} + {{- end }} + {{- end }} + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *{{ $mutation }}) ClearEdge(name string) error { + {{- if $n.Edges }} + switch name { + {{- range $e := $n.Edges }} + {{- if $e.Unique }} + {{- $const := print $n.Package "." $e.Constant }} + case {{ $const }}: + m.Clear{{ $e.StructField }}() + return nil + {{- end }} + {{- end }} + } + {{- end }} + return fmt.Errorf("unknown {{ $n.Name }} unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *{{ $mutation }}) ResetEdge(name string) error { + switch name { + {{- range $e := $n.Edges }} + {{- $const := print $n.Package "." $e.Constant }} + case {{ $const }}: + m.Reset{{ $e.StructField }}() + return nil + {{- end }} + } + return fmt.Errorf("unknown {{ $n.Name }} edge %s", name) +} +{{ end }} + +{{ end }} \ No newline at end of file diff --git a/entc/gen/template/builder/query.tmpl b/entc/gen/template/builder/query.tmpl index 85a6dd735..4373b1fec 100644 --- a/entc/gen/template/builder/query.tmpl +++ b/entc/gen/template/builder/query.tmpl @@ -11,6 +11,13 @@ in the LICENSE file in the root directory of this source tree. {{ template "import" $ }} +import ( + {{- range $path := $.SiblingImports }} + "{{ $path }}" + {{- end }} +) + + {{ $builder := $.QueryName }} {{ $receiver := receiver $builder }} diff --git a/entc/gen/template/builder/setter.tmpl b/entc/gen/template/builder/setter.tmpl index caa49e4db..d1c63776e 100644 --- a/entc/gen/template/builder/setter.tmpl +++ b/entc/gen/template/builder/setter.tmpl @@ -21,11 +21,11 @@ in the LICENSE file in the root directory of this source tree. {{ $func := print "Set" $f.StructField }} // {{ $func }} sets the {{ $f.Name }} field. func ({{ $receiver }} *{{ $builder }}) {{ $func }}({{ $p }} {{ $f.Type }}) *{{ $builder }} { - {{ $receiver }}.{{ $f.BuilderField }} = &{{ $p }} {{- /* setting numeric type override previous calls to Add. */}} {{- if and $f.Type.Numeric $updater }} - {{ $receiver }}.add{{ $f.BuilderField }} = nil + {{ $receiver }}.mutation.{{ print "Reset" $f.StructField }}() {{- end }} + {{ $receiver }}.mutation.{{ $func }}({{ $p }}) return {{ $receiver }} } @@ -45,11 +45,7 @@ in the LICENSE file in the root directory of this source tree. {{ $func := print "Add" $f.StructField }} // {{ $func }} adds {{ $p }} to {{ $f.Name }}. func ({{ $receiver }} *{{ $builder }}) {{ $func }}({{ $p }} {{ $f.Type }}) *{{ $builder }} { - if {{ $receiver }}.add{{ $f.BuilderField }} == nil { - {{ $receiver }}.add{{ $f.BuilderField }} = &{{ $p }} - } else { - *{{ $receiver }}.add{{ $f.BuilderField }} += {{ $p }} - } + {{ $receiver }}.mutation.{{ $func }}({{ $p }}) return {{ $receiver }} } {{ end }} @@ -58,8 +54,7 @@ in the LICENSE file in the root directory of this source tree. {{ $func := print "Clear" $f.StructField }} // {{ $func }} clears the value of {{ $f.Name }}. func ({{ $receiver }} *{{ $builder }}) {{ $func }}() *{{ $builder }} { - {{ $receiver }}.{{ $f.BuilderField }} = nil - {{ $receiver }}.clear{{ $f.BuilderField }} = true + {{ $receiver }}.mutation.{{ $func }}() return {{ $receiver }} } {{ end }} @@ -70,16 +65,7 @@ in the LICENSE file in the root directory of this source tree. {{ $idsFunc := print (pascal $op) (singular $e.Name | pascal) "IDs" }}{{ if $e.Unique }}{{ $idsFunc = print (pascal $op) (pascal $e.Name) "ID" }}{{ end }} // {{ $idsFunc }} {{ $op }}s the {{ $e.Name }} edge to {{ $e.Type.Name }} by id{{ if not $e.Unique }}s{{ end }}. func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }} {{ $e.Type.ID.Type }}) *{{ $builder }} { - if {{ $receiver }}.{{ $e.BuilderField }} == nil { - {{ $receiver }}.{{ $e.BuilderField }} = make(map[{{ $e.Type.ID.Type }}]struct{}) - } - {{ if $e.Unique -}} - {{ $receiver }}.{{ $e.BuilderField }}[id] = struct{}{} - {{- else -}} - for i := range ids { - {{ $receiver }}.{{ $e.BuilderField }}[ids[i]] = struct{}{} - } - {{- end }} + {{ $receiver }}.mutation.{{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }}) return {{ $receiver }} } {{ if and $e.Unique $e.Optional }} diff --git a/entc/gen/template/builder/update.tmpl b/entc/gen/template/builder/update.tmpl index 0eb72ca48..6dde6cb5c 100644 --- a/entc/gen/template/builder/update.tmpl +++ b/entc/gen/template/builder/update.tmpl @@ -11,8 +11,16 @@ in the LICENSE file in the root directory of this source tree. {{ template "import" $ }} +import ( + {{- range $path := $.SiblingImports }} + "{{ $path }}" + {{- end }} +) + + {{ $builder := print (pascal $.Name) "Update" }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} // {{ $builder }} is the builder for updating {{ $.Name }} entities. type {{ $builder }} struct { @@ -40,7 +48,30 @@ func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (int, error) { {{ with extend $ "Receiver" $receiver "Package" $pkg "ZeroValue" 0 -}} {{ template "update/save" . }} {{- end -}} - return {{ $receiver }}.{{ $.Storage }}Save(ctx) + var ( + err error + affected int + ) + if len({{ $receiver }}.hooks) == 0 { + affected, err = {{ $receiver }}.{{ $.Storage }}Save(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*{{ $.MutationName }}) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + {{ $mutation }} = mutation + affected, err = {{ $receiver }}.{{ $.Storage }}Save(ctx) + return affected, err + }) + for i := len({{ $receiver }}.hooks); i > 0; i-- { + mut = {{ $receiver }}.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, {{ $mutation }}); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -72,11 +103,11 @@ func ({{ $receiver }} *{{ $builder }}) ExecX(ctx context.Context) { {{ $onebuilder := printf "%sOne" $builder }} {{ $receiver = receiver $onebuilder }} +{{ $mutation = print $receiver ".mutation" }} // {{ $onebuilder }} is the builder for updating a single {{ $.Name }} entity. type {{ $onebuilder }} struct { config - id {{ $.ID.Type }} {{- template "update/fields" $ }} } @@ -94,7 +125,30 @@ func ({{ $receiver }} *{{ $onebuilder }} ) Save(ctx context.Context) (*{{ $.Name {{ with extend $ "Receiver" $receiver "Package" $pkg "ZeroValue" "nil" -}} {{ template "update/save" . }} {{- end -}} - return {{ $receiver }}.{{ $.Storage }}Save(ctx) + var ( + err error + node *{{ $.Name }} + ) + if len({{ $receiver }}.hooks) == 0 { + node, err = {{ $receiver }}.{{ $.Storage }}Save(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*{{ $.MutationName }}) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + {{ $mutation }} = mutation + node, err = {{ $receiver }}.{{ $.Storage }}Save(ctx) + return node, err + }) + for i := len({{ $receiver }}.hooks); i > 0; i-- { + mut = {{ $receiver }}.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, {{ $mutation }}); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -128,37 +182,22 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) { {{/* shared struct fields between the two updaters */}} {{ define "update/fields"}} -{{ range $_, $f := $.Fields }} - {{- if or (not $f.Immutable) $f.UpdateDefault }} - {{- $f.BuilderField }} *{{ $f.Type }} - {{- if $f.Type.Numeric }} - add{{ $f.BuilderField }} *{{ $f.Type }} - {{- end }} - {{- end }} - {{- if $f.Optional }} - clear{{ $f.BuilderField }} bool - {{- end }} -{{ end }} -{{- range $_, $e := $.Edges }} - {{- $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{} -{{ end }} -{{- range $_, $e := $.Edges }} - {{- $p := "removed" }}{{ if $e.Unique }}{{ $p = "cleared" }}{{ end }} - {{- print $p $e.StructField }} {{ if $e.Unique }}bool{{ else }}map[{{ $e.Type.ID.Type }}]struct{}{{ end }} -{{ end -}} + hooks []Hook + mutation *{{ $.MutationName }} {{ end }} {{/* shared edges removal between the two updaters */}} {{ define "update/edges" }} {{ $builder := pascal .Scope.Builder }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} {{ range $_, $e := $.Edges }} {{ if $e.Unique }} {{ $func := print "Clear" $e.StructField }} // {{ $func }} clears the {{ $e.Name }} edge to {{ $e.Type.Name }}. func ({{ $receiver }} *{{ $builder }}) {{ $func }}() *{{ $builder }} { - {{ $receiver }}.cleared{{ $e.StructField }} = true + {{ $mutation }}.{{ $func }}() return {{ $receiver }} } {{ else }} @@ -168,12 +207,7 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) { {{ $idsFunc := print "Remove" (singular $e.Name | pascal) "IDs" }} // {{ $idsFunc }} removes the {{ $e.Name }} edge to {{ $e.Type.Name }} by ids. func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}(ids ...{{ $e.Type.ID.Type }}) *{{ $builder }} { - if {{ $receiver }}.removed{{ $e.StructField }} == nil { - {{ $receiver }}.removed{{ $e.StructField }} = make(map[{{ $e.Type.ID.Type }}]struct{}) - } - for i := range ids { - {{ $receiver }}.removed{{ $e.StructField }}[ids[i]] = struct{}{} - } + {{ $mutation }}.{{ $idsFunc }}(ids...) return {{ $receiver }} } {{ $func := print "Remove" $e.StructField }} @@ -195,31 +229,28 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) { {{- $pkg := .Scope.Package -}} {{- $zero := .Scope.ZeroValue }} {{- $receiver := .Scope.Receiver -}} +{{- $mutation := print $receiver ".mutation" -}} + {{- range $_, $f := $.Fields -}} {{- if $f.UpdateDefault -}} - if {{ $receiver }}.{{ $f.BuilderField }} == nil {{ if $f.Optional }} && !{{ $receiver }}.clear{{ $f.BuilderField }} {{ end }} { + if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok {{ if $f.Optional }} && !{{ $mutation }}.{{ $f.StructField }}Cleared() {{ end }} { v := {{ $.Package }}.{{ $f.UpdateDefaultName }}{{ if $f.IsTime }}(){{ end }} - {{ $receiver }}.{{ $f.BuilderField }} = &v + {{ $mutation }}.Set{{ $f.StructField }}(v) } {{ end -}} {{ with and (or $f.Validators $f.IsEnum) (not $f.Immutable) -}} - if {{ $receiver }}.{{ $f.BuilderField }} != nil { - if err := {{ $.Package }}.{{ $f.Validator }}(*{{ $receiver }}.{{ $f.BuilderField }}); err != nil { + if v, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { + if err := {{ $.Package }}.{{ $f.Validator }}(v); err != nil { return {{ $zero }}, fmt.Errorf("{{ $pkg }}: validator failed for field \"{{ $f.Name }}\": %v", err) } } {{ end -}} {{ end -}} {{- range $_, $e := $.Edges }} - {{- if $e.Unique -}} - if len({{ $receiver }}.{{ $e.BuilderField }}) > 1 { - return {{ $zero }}, errors.New("{{ $pkg }}: multiple assignments on a unique edge \"{{ $e.Name }}\"") + {{ if and $e.Unique (not $e.Optional) -}} + if _, ok := {{ $mutation }}.{{ $e.StructField }}ID(); {{ $mutation }}.{{ $e.StructField }}Cleared() && !ok { + return {{ $zero }}, errors.New("{{ $pkg }}: clearing a unique edge \"{{ $e.Name }}\"") } - {{ if not $e.Optional -}} - if {{ $receiver }}.cleared{{ $e.StructField }} && {{ $receiver }}.{{ $e.BuilderField }} == nil { - return {{ $zero }}, errors.New("{{ $pkg }}: clearing a unique edge \"{{ $e.Name }}\"") - } - {{ end -}} {{ end -}} {{ end -}} {{ end }} diff --git a/entc/gen/template/client.tmpl b/entc/gen/template/client.tmpl index 10a06d507..d880be85f 100644 --- a/entc/gen/template/client.tmpl +++ b/entc/gen/template/client.tmpl @@ -30,26 +30,29 @@ type Client struct { // Schema is the client for creating, migrating and dropping schema. Schema *migrate.Schema {{- end }} - {{ range $_, $n := $.Nodes -}} + {{- range $n := $.Nodes }} // {{ $n.Name }} is the client for interacting with the {{ $n.Name }} builders. {{ $n.Name }} *{{ $n.Name }}Client - {{ end }} + {{- end }} {{ template "client/fields/additional" $ }} } // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - {{- if $.SupportMigrate }} - Schema: migrate.NewSchema(c.driver), - {{- end }} - {{ range $_, $n := $.Nodes -}} - {{ $n.Name }}: New{{ $n.Name }}Client(c), - {{ end -}} - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + {{- if $.SupportMigrate }} + c.Schema = migrate.NewSchema(c.driver) + {{- end }} + {{- range $n := $.Nodes }} + c.{{ $n.Name }} = New{{ $n.Name }}Client(c.config) + {{- end }} } // Open opens a connection to the database specified by the driver name and a @@ -74,7 +77,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("{{ $pkg }}: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, {{ range $_, $n := $.Nodes -}} @@ -94,16 +97,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - {{- if $.SupportMigrate }} - Schema: migrate.NewSchema(cfg.driver), - {{- end }} - {{ range $_, $n := $.Nodes -}} - {{ $n.Name }}: New{{ $n.Name }}Client(cfg), - {{ end -}} - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -111,7 +108,16 @@ func (c *Client) Close() error { return c.driver.Close() } -{{ range $_, $n := $.Nodes -}} +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + {{- range $_, $n := $.Nodes }} + c.{{ $n.Name }}.Use(hooks...) + {{- end }} +} + + +{{ range $_, $n := $.Nodes }} {{ $client := print $n.Name "Client" }} // {{ $client }} is a client for the {{ $n.Name }} schema. type {{ $client }} struct { @@ -125,14 +131,22 @@ func New{{ $client }}(c config) *{{ $client }} { return &{{ $client }}{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `{{ $n.Package }}.Hooks(f(g(h())))`. +func (c *{{ $client }}) Use(hooks ...Hook) { + c.hooks.{{ $n.Name }} = append(c.hooks.{{ $n.Name }}, hooks...) +} + // Create returns a create builder for {{ $n.Name }}. func (c *{{ $client }}) Create() *{{ $n.Name }}Create { - return &{{ $n.Name }}Create{config: c.config} + mutation := new{{ $n.MutationName }}(c.config, OpCreate) + return &{{ $n.Name }}Create{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for {{ $n.Name }}. func (c *{{ $client }}) Update() *{{ $n.Name }}Update { - return &{{ $n.Name }}Update{config: c.config} + mutation := new{{ $n.MutationName }}(c.config, OpUpdate) + return &{{ $n.Name }}Update{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -142,12 +156,15 @@ func (c *{{ $client }}) UpdateOne({{ $rec }} *{{ $n.Name }}) *{{ $n.Name }}Updat // UpdateOneID returns an update builder for the given id. func (c *{{ $client }}) UpdateOneID(id {{ $n.ID.Type }}) *{{ $n.Name }}UpdateOne { - return &{{ $n.Name }}UpdateOne{config: c.config, id: id} + mutation := new{{ $n.MutationName }}(c.config, OpUpdateOne) + mutation.id = &id + return &{{ $n.Name }}UpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for {{ $n.Name }}. func (c *{{ $client }}) Delete() *{{ $n.Name }}Delete { - return &{{ $n.Name }}Delete{config: c.config} + mutation := new{{ $n.MutationName }}(c.config, OpDelete) + return &{{ $n.Name }}Delete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -157,7 +174,10 @@ func (c *{{ $client }}) DeleteOne({{ $rec }} *{{ $n.Name }}) *{{ $n.Name }}Delet // DeleteOneID returns a delete builder for the given id. func (c *{{ $client }}) DeleteOneID(id {{ $n.ID.Type }}) *{{ $n.Name }}DeleteOne { - return &{{ $n.Name }}DeleteOne{c.Delete().Where({{ $n.Package }}.ID(id))} + builder := c.Delete().Where({{ $n.Package }}.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &{{ $n.Name }}DeleteOne{builder} } // Create returns a query builder for {{ $n.Name }}. @@ -192,6 +212,16 @@ func (c *{{ $client }}) Query{{ pascal $e.Name }}({{ $rec }} *{{ $n.Name }}) *{{ } {{ end }} +// Hooks returns the client hooks. +func (c *{{ $client }}) Hooks() []Hook { + {{- if or $n.NumHooks $n.HasPolicy }} + hooks := c.hooks.{{ $n.Name }} + return append(hooks[:len(hooks):len(hooks)], {{ $n.Package }}.Hooks[:]...) + {{- else }} + return c.hooks.{{ $n.Name }} + {{- end }} +} + {{ end }} {{ end }} diff --git a/entc/gen/template/config.tmpl b/entc/gen/template/config.tmpl index 486a88eab..e05af5af2 100644 --- a/entc/gen/template/config.tmpl +++ b/entc/gen/template/config.tmpl @@ -22,6 +22,15 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + {{- range $n := $.Nodes }} + {{ $n.Name }} []ent.Hook + {{- end }} } // Options applies the options on the config object. diff --git a/entc/gen/template/dialect/gremlin/create.tmpl b/entc/gen/template/dialect/gremlin/create.tmpl index d814cb26d..fa25516af 100644 --- a/entc/gen/template/dialect/gremlin/create.tmpl +++ b/entc/gen/template/dialect/gremlin/create.tmpl @@ -7,6 +7,7 @@ in the LICENSE file in the root directory of this source tree. {{ define "dialect/gremlin/create" }} {{ $builder := pascal $.Scope.Builder }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} func ({{ $receiver }} *{{ $builder }}) gremlinSave(ctx context.Context) (*{{ $.Name }}, error) { res := &gremlin.Response{} @@ -34,23 +35,23 @@ func ({{ $receiver }} *{{ $builder }}) gremlin() *dsl.Traversal { {{- end }} v := g.AddV({{ $.Package }}.Label) {{- range $_, $f := $.Fields }} - if {{ $receiver }}.{{- $f.BuilderField }} != nil { + if value, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { {{- if $f.Unique }} constraints = append(constraints, &constraint{ - pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.BuilderField }}).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.BuilderField }})), + pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, value)), }) {{- end }} - v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.BuilderField }}) + v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, value) } {{- end }} {{- range $_, $e := $.Edges }} {{- $direction := "In" }} - {{- $name := printf "%s.%s" $.Package $e.Constant }} - for id := range {{ $receiver }}.{{ $e.BuilderField }} { + {{- $name := printf "%s.%s" $.Package $e.LabelConstant }} + for _, id := range {{ $mutation }}.{{ $e.StructField }}IDs() { {{- if $e.IsInverse }} {{- $direction = "Out" }} - {{- $name = printf "%s.%s" $e.Type.Package $e.Constant }} + {{- $name = printf "%s.%s" $e.Type.Package $e.LabelConstant }} v.AddE({{ $name }}).From(g.V(id)).InV() {{- else }} v.AddE({{ $name }}).To(g.V(id)).OutV() diff --git a/entc/gen/template/dialect/gremlin/meta.tmpl b/entc/gen/template/dialect/gremlin/meta.tmpl index 5ae658022..e31990c04 100644 --- a/entc/gen/template/dialect/gremlin/meta.tmpl +++ b/entc/gen/template/dialect/gremlin/meta.tmpl @@ -6,8 +6,8 @@ in the LICENSE file in the root directory of this source tree. {{/* constants needed for gremlin dialects. */}} {{ define "dialect/gremlin/meta/constants" }} - {{ range $_, $e := $.Edges }}{{ $label := $e.Constant -}} - {{ if $e.IsInverse }}{{- $label = $e.InverseConstant -}} + {{ range $_, $e := $.Edges }}{{ $label := $e.LabelConstant -}} + {{ if $e.IsInverse }}{{- $label = $e.InverseLabelConstant -}} // {{ $label }} holds the string label denoting the {{ lower $e.Name }} inverse edge type in the database. {{ else -}} // {{ $label }} holds the string label denoting the {{ lower $e.Name }} edge type in the database. diff --git a/entc/gen/template/dialect/gremlin/predicate.tmpl b/entc/gen/template/dialect/gremlin/predicate.tmpl index 783f73c1d..41fc540de 100644 --- a/entc/gen/template/dialect/gremlin/predicate.tmpl +++ b/entc/gen/template/dialect/gremlin/predicate.tmpl @@ -47,12 +47,12 @@ in the LICENSE file in the root directory of this source tree. {{ define "dialect/gremlin/predicate/edge/has" -}} {{- $e := $.Scope.Edge -}} - {{- $label := $e.Constant -}} + {{- $label := $e.LabelConstant -}} {{- $direction := "Out" -}} {{- if $e.IsInverse -}} {{- $direction = "In" -}} {{/* avoid circular dependecies */}} - {{- $label = $e.InverseConstant -}} + {{- $label = $e.InverseLabelConstant -}} {{- end -}} func(t *dsl.Traversal) { {{- /* if it's an edge with self-reference, take the two vertices */}} @@ -66,14 +66,14 @@ in the LICENSE file in the root directory of this source tree. {{ define "dialect/gremlin/predicate/edge/haswith" -}} {{- $e := $.Scope.Edge -}} - {{- $label := $e.Constant -}} + {{- $label := $e.LabelConstant -}} {{- $direction := "Out" -}} {{- $inverse_direction := "In" -}} {{- if $e.IsInverse -}} {{- $direction = "In" -}} {{- $inverse_direction = "Out" -}} {{/* avoid circular dependecies */}} - {{- $label = $e.InverseConstant -}} + {{- $label = $e.InverseLabelConstant -}} {{- end -}} func(t *dsl.Traversal) { {{- if $e.Bidi }}{{/* selfref means it should be true in one of the directions */}} diff --git a/entc/gen/template/dialect/gremlin/query.tmpl b/entc/gen/template/dialect/gremlin/query.tmpl index e346c6694..6c1255373 100644 --- a/entc/gen/template/dialect/gremlin/query.tmpl +++ b/entc/gen/template/dialect/gremlin/query.tmpl @@ -75,11 +75,11 @@ func ({{ $receiver }} *{{ $builder }}) gremlinQuery() *dsl.Traversal { {{- $receiver := $.Scope.Receiver }} gremlin := {{ $receiver }}.gremlinQuery() {{- if $e.Bidi }} - query.gremlin = gremlin.Both({{ $.Package }}.{{ $e.Constant }}) + query.gremlin = gremlin.Both({{ $.Package }}.{{ $e.LabelConstant }}) {{- else if $e.IsInverse }} - query.gremlin = gremlin.InE({{ $e.Type.Package }}.{{ $e.Constant }}).OutV() + query.gremlin = gremlin.InE({{ $e.Type.Package }}.{{ $e.LabelConstant }}).OutV() {{- else }} - query.gremlin = gremlin.OutE({{ $.Package }}.{{ $e.Constant }}).InV() + query.gremlin = gremlin.OutE({{ $.Package }}.{{ $e.LabelConstant }}).InV() {{- end }} {{ end }} @@ -91,10 +91,10 @@ func ({{ $receiver }} *{{ $builder }}) gremlinQuery() *dsl.Traversal { {{- $receiver := $.Scope.Receiver }} {{- if $e.Bidi }} - query.gremlin = g.V({{ $receiver }}.ID).Both({{ $n.Package }}.{{ $e.Constant }}) + query.gremlin = g.V({{ $receiver }}.ID).Both({{ $n.Package }}.{{ $e.LabelConstant }}) {{- else if $e.IsInverse }} - query.gremlin = g.V({{ $receiver }}.ID).InE({{ $e.Type.Package }}.{{ $e.Constant }}).OutV() + query.gremlin = g.V({{ $receiver }}.ID).InE({{ $e.Type.Package }}.{{ $e.LabelConstant }}).OutV() {{- else }} - query.gremlin = g.V({{ $receiver }}.ID).OutE({{ $n.Package }}.{{ $e.Constant }}).InV() + query.gremlin = g.V({{ $receiver }}.ID).OutE({{ $n.Package }}.{{ $e.LabelConstant }}).InV() {{- end }} {{ end }} diff --git a/entc/gen/template/dialect/gremlin/update.tmpl b/entc/gen/template/dialect/gremlin/update.tmpl index 1975afe07..e2f21c6fb 100644 --- a/entc/gen/template/dialect/gremlin/update.tmpl +++ b/entc/gen/template/dialect/gremlin/update.tmpl @@ -7,12 +7,21 @@ in the LICENSE file in the root directory of this source tree. {{ define "dialect/gremlin/update" }} {{ $builder := pascal $.Scope.Builder }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} {{ $one := hasSuffix $builder "One" }} {{ $zero := 0 }}{{ if $one }}{{ $zero = "nil" }}{{ end }} func ({{ $receiver }} *{{ $builder }}) gremlinSave(ctx context.Context) ({{- if $one }}*{{ $.Name }}{{ else }}int{{ end }}, error) { res := &gremlin.Response{} - query, bindings := {{ $receiver }}.gremlin({{- if $one }}{{ $receiver }}.id{{ end }}).Query() + {{- if $one }} + id, ok := {{ $mutation }}.{{ $.ID.MutationGet }}() + if !ok { + return {{ $zero }}, fmt.Errorf("missing {{ $.Name }}.ID for update") + } + query, bindings := {{ $receiver }}.gremlin(id).Query() + {{- else }} + query, bindings := {{ $receiver }}.gremlin().Query() + {{- end }} if err := {{ $receiver }}.driver.Exec(ctx, query, bindings, res); err != nil { return {{ $zero }}, err } @@ -58,25 +67,25 @@ func ({{ $receiver }} *{{ $builder }}) gremlin({{ if $one }}id {{ $.ID.Type }}{{ ) {{- range $_, $f := $.Fields }} {{- if or (not $f.Immutable) $f.UpdateDefault }} - if value := {{ $receiver }}.{{ $f.BuilderField }}; value != nil { + if value, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { {{- if $f.Unique }} constraints = append(constraints, &constraint{ - pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *value)), + pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, value)), }) {{- end }} - v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, *value) + v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, value) } {{- if $f.Type.Numeric }} - if value := {{ $receiver }}.add{{ $f.BuilderField }}; value != nil { + if value, ok := {{ $mutation }}.Added{{ $f.StructField }}(); ok { {{- if $f.Unique }} - addValue := rv.Clone().Union(__.Values({{ $.Package }}.{{ $f.Constant }}), __.Constant(*value)).Sum().Next() + addValue := rv.Clone().Union(__.Values({{ $.Package }}.{{ $f.Constant }}), __.Constant(value)).Sum().Next() constraints = append(constraints, &constraint{ pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, addValue).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, fmt.Sprintf("+= %v", *value))), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, fmt.Sprintf("+= %v", value))), }) {{- end }} - v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, __.Union(__.Values({{ $.Package }}.{{ $f.Constant }}), __.Constant(*value)).Sum()) + v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, __.Union(__.Values({{ $.Package }}.{{ $f.Constant }}), __.Constant(value)).Sum()) } {{- end }} {{- end }} @@ -86,7 +95,7 @@ func ({{ $receiver }} *{{ $builder }}) gremlin({{ if $one }}id {{ $.ID.Type }}{{ var properties []interface{} {{- range $_, $f := $.Fields }} {{- if $f.Optional }} - if {{ $receiver }}.clear{{ $f.BuilderField }} { + if {{ $mutation }}.{{ $f.StructField }}Cleared() { properties = append(properties, {{ $.Package }}.{{ $f.Constant }}) } {{- end }} @@ -97,16 +106,16 @@ func ({{ $receiver }} *{{ $builder }}) gremlin({{ if $one }}id {{ $.ID.Type }}{{ {{- end }} {{- range $_, $e := $.Edges }} {{- $direction := "In" }} - {{- $name := printf "%s.%s" $.Package $e.Constant }} + {{- $name := printf "%s.%s" $.Package $e.LabelConstant }} {{- if $e.IsInverse }} {{- $direction = "Out" }} - {{- $name = printf "%s.%s" $e.Type.Package $e.Constant }} + {{- $name = printf "%s.%s" $e.Type.Package $e.LabelConstant }} {{- end }} {{- /* remove edges */}} {{- if $e.Unique }} - if {{ $receiver }}.cleared{{ $e.StructField }} { + if {{ $mutation }}.{{ $e.StructField }}Cleared() { {{- else }} - for id := range {{ $receiver }}.removed{{ $e.StructField }} { + for _, id := range {{ $mutation }}.Removed{{ $e.StructField }}IDs() { {{- end }} {{- if $e.Bidi }} tr := rv.Clone().BothE({{ $name }}){{ if not $e.Unique }}.Where(__.Or(__.InV().HasID(id), __.OutV().HasID(id))){{ end }}.Drop().Iterate() @@ -118,7 +127,7 @@ func ({{ $receiver }} *{{ $builder }}) gremlin({{ if $one }}id {{ $.ID.Type }}{{ trs = append(trs, tr) } {{- /* update edges */}} - for id := range {{ $receiver }}.{{ $e.BuilderField }} { + for _, id := range {{ $mutation }}.{{ $e.StructField }}IDs() { {{- if $e.IsInverse }} v.AddE({{ $name }}).From(g.V(id)).InV() {{- else }} diff --git a/entc/gen/template/dialect/sql/create.tmpl b/entc/gen/template/dialect/sql/create.tmpl index 6d77ba5ec..62d874af8 100644 --- a/entc/gen/template/dialect/sql/create.tmpl +++ b/entc/gen/template/dialect/sql/create.tmpl @@ -7,6 +7,7 @@ in the LICENSE file in the root directory of this source tree. {{ define "dialect/sql/create" }} {{ $builder := pascal $.Scope.Builder }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name }}, error) { var ( @@ -20,23 +21,23 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name } ) {{- if $.ID.UserDefined }} - if value := {{ $receiver }}.{{ $.ID.BuilderField }}; value != nil { - {{ $.Receiver }}.ID = *value - _spec.ID.Value = *value + if id, ok := {{ $mutation }}.{{ $.ID.MutationGet }}(); ok { + {{ $.Receiver }}.ID = id + _spec.ID.Value = id } {{- end }} {{- range $_, $f := $.Fields }} - if value := {{ $receiver }}.{{ $f.BuilderField }}; value != nil { + if value, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.{{ $f.Type.ConstName }}, - Value: *value, + Value: value, Column: {{ $.Package }}.{{ $f.Constant }}, }) - {{ $.Receiver }}.{{ $f.StructField }} = {{ if not $f.Nillable }}*{{ end }}value + {{ $.Receiver }}.{{ $f.StructField }} = {{ if $f.Nillable }}&{{ end }}value } {{- end }} {{- range $_, $e := $.Edges }} - if nodes := {{ $receiver }}.{{ $e.BuilderField }}; len(nodes) > 0 { + if nodes := {{ $mutation }}.{{ $e.StructField }}IDs(); len(nodes) > 0 { {{- with extend $ "Edge" $e "Nodes" true "Zero" "nil" }} {{ template "dialect/sql/defedge" . }}{{/* defined in sql/update.tmpl */}} {{- end }} diff --git a/entc/gen/template/dialect/sql/update.tmpl b/entc/gen/template/dialect/sql/update.tmpl index 9b711b726..14bd3166a 100644 --- a/entc/gen/template/dialect/sql/update.tmpl +++ b/entc/gen/template/dialect/sql/update.tmpl @@ -8,6 +8,7 @@ in the LICENSE file in the root directory of this source tree. {{ $pkg := $.Scope.Package }} {{ $builder := pascal $.Scope.Builder }} {{ $receiver := receiver $builder }} +{{ $mutation := print $receiver ".mutation" }} {{ $one := hasSuffix $builder "One" }} {{- $zero := 0 }}{{ if $one }}{{ $zero = "nil" }}{{ end }} {{- $ret := "n" }}{{ if $one }}{{ $ret = $.Receiver }}{{ end }} @@ -18,15 +19,18 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }} Table: {{ $.Package }}.Table, Columns: {{ $.Package }}.Columns, ID: &sqlgraph.FieldSpec{ - {{- if $one }} - Value: {{ $receiver }}.id, - {{- end }} Type: field.{{ $.ID.Type.ConstName }}, Column: {{ $.Package }}.{{ $.ID.Constant }}, }, }, } - {{- if not $one }} + {{- if $one }} + id, ok := {{ $mutation }}.{{ $.ID.MutationGet }}() + if !ok { + return {{ $zero }}, fmt.Errorf("missing {{ $.Name }}.ID for update") + } + _spec.Node.ID.Value = id + {{- else }} if ps := {{ $receiver }}.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -37,25 +41,25 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }} {{- end }} {{- range $_, $f := $.Fields }} {{- if or (not $f.Immutable) $f.UpdateDefault }} - if value := {{ $receiver }}.{{ $f.BuilderField }}; value != nil { + if value, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.{{ $f.Type.ConstName }}, - Value: *value, + Value: value, Column: {{ $.Package }}.{{ $f.Constant }}, }) } {{- if $f.Type.Numeric }} - if value := {{ $receiver }}.add{{ $f.BuilderField }}; value != nil { + if value, ok := {{ $mutation }}.Added{{ $f.StructField }}(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.{{ $f.Type.ConstName }}, - Value: *value, + Value: value, Column: {{ $.Package }}.{{ $f.Constant }}, }) } {{- end }} {{- end }} {{- if $f.Optional }} - if {{ $receiver }}.clear{{ $f.BuilderField }} { + if {{ $mutation }}.{{ $f.StructField }}Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.{{ $f.Type.ConstName }}, Column: {{ $.Package }}.{{ $f.Constant }}, @@ -65,21 +69,21 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }} {{- end }} {{- range $_, $e := $.Edges }} {{- if $e.Unique }} - if {{ $receiver }}.cleared{{ $e.StructField }} { + if {{ $mutation }}.{{ $e.StructField }}Cleared() { {{- with extend $ "Edge" $e }} {{ template "dialect/sql/defedge" . }} {{- end }} _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } {{- else }} - if nodes := {{ $receiver }}.removed{{ $e.StructField }}; len(nodes) > 0 { + if nodes := {{ $mutation }}.Removed{{ $e.StructField }}IDs(); len(nodes) > 0 { {{- with extend $ "Edge" $e "Nodes" true "Zero" $zero }} {{ template "dialect/sql/defedge" . }} {{- end }} _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } {{- end }} - if nodes := {{ $receiver }}.{{ $e.BuilderField }}; len(nodes) > 0 { + if nodes := {{ $mutation }}.{{ $e.StructField }}IDs(); len(nodes) > 0 { {{- with extend $ "Edge" $e "Nodes" true "Zero" $zero }} {{ template "dialect/sql/defedge" . }} {{- end }} @@ -123,7 +127,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }} }, } {{- with $.Scope.Nodes }} - for k, _ := range nodes { + for _, k := range nodes { {{- $id := $e.Type.ID -}} {{- /* Convert string-ids that are stored as int in the database */ -}} {{- if and (not $id.UserDefined) $id.IsString }} diff --git a/entc/gen/template/hook.tmpl b/entc/gen/template/hook.tmpl new file mode 100644 index 000000000..f040f63c2 --- /dev/null +++ b/entc/gen/template/hook.tmpl @@ -0,0 +1,66 @@ +{{/* +Copyright 2019-present Facebook Inc. All rights reserved. +This source code is licensed under the Apache 2.0 license found +in the LICENSE file in the root directory of this source tree. +*/}} + +{{ define "hook" }} + +{{ with extend $ "Package" "hook" }} + {{ template "header" . }} +{{ end }} + +import "{{ $.Config.Package }}" + +{{ range $n := $.Nodes }} + {{ $name := print $n.Name "Func" }} + {{ $type := print "*ent." $n.MutationName }} + + // The {{ $name }} type is an adapter to allow the use of ordinary + // function as {{ $n.Name }} mutator. + type {{ $name }} func(context.Context, {{ $type }}) (ent.Value, error) + + // Mutate calls f(ctx, m). + func (f {{ $name }}) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.({{ $type }}) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect {{ $type }}", m) + } + return f(ctx, mv) + } +{{ end }} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} +{{ end }} \ No newline at end of file diff --git a/entc/gen/template/import.tmpl b/entc/gen/template/import.tmpl index 7c61d7b82..06a6f8f08 100644 --- a/entc/gen/template/import.tmpl +++ b/entc/gen/template/import.tmpl @@ -16,10 +16,6 @@ import ( {{- /* ignore generting on graph specififc templates */}} {{- if not (eq $.Config.Package $.Package) }} "{{ $.Config.Package }}/predicate" - "{{ $.Config.Package }}/{{ $.Package }}" - {{- with $.Config.Schema }} - "{{ . }}" - {{- end }} {{- range $_, $f := $.Fields }} {{- with $f.Type.PkgPath }} "{{ . }}" diff --git a/entc/gen/template/meta.tmpl b/entc/gen/template/meta.tmpl index 38b7146ab..738c7935e 100644 --- a/entc/gen/template/meta.tmpl +++ b/entc/gen/template/meta.tmpl @@ -17,10 +17,17 @@ const ( Label = "{{ $.Label }}" // {{ $.ID.Constant }} holds the string denoting the id field in the database. {{ $.ID.Constant }} = "{{ $.ID.StorageKey }}" - {{ range $_, $f := $.Fields -}}{{ $field := $f.Constant -}} + {{- range $f := $.Fields -}}{{ $field := $f.Constant -}} // {{ $field }} holds the string denoting the {{ lower $f.Name }} vertex property in the database. {{ $field }} = "{{ $f.StorageKey }}" - {{ end -}} + {{- end }} + + {{ range $e := $.Edges }} + {{- $edge := $e.Constant }} + // {{ $edge }} holds the string denoting the {{ lower $e.Name }} edge name in mutations. + {{ $edge }} = "{{ $e.Name }}" + {{- end }} + {{ $tmpl := printf "dialect/%s/meta/constants" $.Storage }} {{ xtemplate $tmpl $ }} ) @@ -30,69 +37,44 @@ const ( {{ xtemplate $tmpl $ }} {{ end }} -{{ if or $.HasDefault $.HasValidators }} -var ( - {{- with $.MixedInWithDefaultOrValidator }} - mixin = {{ base $.Schema }}.{{ $.Name }}{}.Mixin() - mixinFields = [...][]ent.Field{ - {{- range $i, $_ := xrange $.NumMixin }} - mixin[{{ $i }}].Fields(), - {{- end }} - } +{{ if or $.HasDefault $.HasValidators $.NumHooks $.HasPolicy }} + {{- $numHooks := $.NumHooks }} + {{- if $.HasPolicy }} + {{- $numHooks = add $numHooks 1 }} + {{- end }} + {{- if $numHooks }} + // Note that the variables below are initialized by the runtime + // package on the initialization of the application. Therefore, + // it should be imported in the main as follows: + // + // import _ "{{ $.Config.Package }}/runtime" + // {{- end }} - fields = {{ base $.Schema }}.{{ $.Name }}{}.Fields() - {{ range $i, $f := $.Fields -}} - {{- $desc := print "desc" $f.StructField -}} - {{- /* enum default values handled near their declarations. */}} - {{ if or (and $f.Default (not $f.IsEnum)) $f.UpdateDefault $f.Validators -}} - {{- if $f.Position.MixedIn }} - // {{ $desc }} is the schema descriptor for {{ $f.Name }} field. - {{ $desc }} = mixinFields[{{ $f.Position.MixinIndex }}][{{ $f.Position.Index }}].Descriptor() - {{- else }} - // {{ $desc }} is the schema descriptor for {{ $f.Name }} field. - {{ $desc }} = fields[{{ $f.Position.Index }}].Descriptor() + var ( + {{- if $numHooks }} + Hooks [{{ $numHooks }}]ent.Hook + {{- end }} + {{- range $f := $.Fields }} + {{- if and $f.Default (not $f.IsEnum) }} + {{- $default := $f.DefaultName }} + // {{ $default }} holds the default value on creation for the {{ $f.Name }} field. + {{ $default }} {{ if or $f.IsTime $f.IsUUID }}func() {{ end }}{{ $f.Type }} {{- end }} - {{ end -}} - {{ if and $f.Default (not $f.IsEnum) }} - {{- $default := $f.DefaultName -}} - // {{ $default }} holds the default value on creation for the {{ $f.Name }} field. - {{ $default }} = {{ $desc }}.Default.({{ if or $f.IsTime $f.IsUUID }}func() {{ end }}{{ $f.Type }}) - {{ end -}} - {{ if $f.UpdateDefault }} - {{- $default := $f.UpdateDefaultName -}} - // {{ $default }} holds the default value on update for the {{ $f.Name }} field. - {{ $default }} = {{ $desc }}.UpdateDefault.({{ if $f.IsTime }}func() {{ end }}{{ $f.Type }}) - {{ end -}} - {{ with $f.Validators -}} - {{ $name := $f.Validator -}} - {{ $type := printf "func (%s) error" $f.Type -}} - // {{ $name }} is a validator for the "{{ $f.Name }}" field. It is called by the builders before save. - {{ if eq $f.Validators 1 -}} - {{ $name }} = {{ $desc }}.Validators[0].({{ $type }}) - {{ else -}} - {{ $name }} = func() {{ $type }} { - validators := {{ $desc }}.Validators - fns := [...]func({{ $f.Type }}) error { - {{- range $j, $n := xrange $f.Validators }} - validators[{{ $j }}].(func({{ $f.Type }}) error), - {{- end }} - } - return func({{ $f.BuilderField }} {{ $f.Type }}) error { - for _, fn := range fns { - if err := fn({{ $f.BuilderField }}); err != nil { - return err - } - } - return nil - } - }() - {{ end -}} - {{ end -}} - {{ end -}} -) + {{- if $f.UpdateDefault }} + {{- $default := $f.UpdateDefaultName }} + // {{ $default }} holds the default value on update for the {{ $f.Name }} field. + {{ $default }} {{ if $f.IsTime }}func() {{ end }}{{ $f.Type }} + {{- end }} + {{- with $f.Validators }} + {{- $name := $f.Validator }} + {{- $type := printf "func (%s) error" $f.Type }} + // {{ $name }} is a validator for the "{{ $f.Name }}" field. It is called by the builders before save. + {{ $name }} {{ $type }} + {{- end }} + {{- end }} + ) {{ end }} - {{/* define custom type for enum fields */}} {{ range $_, $f := $.Fields -}} {{ if $f.IsEnum }} diff --git a/entc/gen/template/migrate/schema.tmpl b/entc/gen/template/migrate/schema.tmpl index eb698f36d..88807a6ab 100644 --- a/entc/gen/template/migrate/schema.tmpl +++ b/entc/gen/template/migrate/schema.tmpl @@ -35,7 +35,7 @@ var ( {{- with $c.Size }} Size: {{ . }},{{ end }} {{- with $c.Attr }} Attr: "{{ . }}",{{ end }} {{- with $c.Enums }} Enums: []string{ {{ range $i, $e := . }}"{{ $e }}",{{ end }} },{{ end }} - {{- with $c.Default }} Default: {{ $node.Package }}.{{ . }},{{ end }}}, + {{- with $c.Default }} Default: {{ . }},{{ end }}}, {{- end }} } {{- $table := pascal $t.Name | printf "%sTable" }} diff --git a/entc/gen/template/privacy.tmpl b/entc/gen/template/privacy.tmpl new file mode 100644 index 000000000..137041eec --- /dev/null +++ b/entc/gen/template/privacy.tmpl @@ -0,0 +1,169 @@ +{{/* +Copyright 2019-present Facebook Inc. All rights reserved. +This source code is licensed under the Apache 2.0 license found +in the LICENSE file in the root directory of this source tree. +*/}} + +{{ define "privacy" }} + +{{- with extend $ "Package" "privacy" -}} + {{ template "header" . }} +{{ end }} + +import "{{ $.Config.Package }}" + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +{{- range $decision := list "Allow" "Deny" "Skip" }} + // {{ $decision }}f returns an formatted wrapped {{ $decision }} decision. + func {{ $decision }}f(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, {{ $decision }})...) + } +{{- end }} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct { err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +{{- range $n := $.Nodes }} + {{ $name := print $n.Name "ReadRuleFunc" }} + {{ $type := print "*ent." $n.Name }} + // The {{ $name }} type is an adapter to allow the use of ordinary + // functions as a read rule. + type {{ $name }} func(context.Context, {{ $type }}) error + + // EvalRead calls f(ctx, v). + func (f {{ $name }}) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.({{ $type }}); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect {{ $type }}", v) + } + + {{ $name = print $n.Name "WriteRuleFunc" }} + {{ $type = print "*ent." $n.MutationName }} + // The {{ $name }} type is an adapter to allow the use of ordinary + // functions as a write rule. + type {{ $name }} func(context.Context, {{ $type }}) error + + // EvalWrite calls f(ctx, m). + func (f {{ $name }}) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.({{ $type }}); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect {{ $type }}", m) + } +{{- end }} + +{{ end }} diff --git a/entc/gen/template/runtime.tmpl b/entc/gen/template/runtime.tmpl new file mode 100644 index 000000000..50e082975 --- /dev/null +++ b/entc/gen/template/runtime.tmpl @@ -0,0 +1,169 @@ +{{/* +Copyright 2019-present Facebook Inc. All rights reserved. +This source code is licensed under the Apache 2.0 license found +in the LICENSE file in the root directory of this source tree. +*/}} + +{{/* +The runtime template generates the schema-stitching logic and holds the +module version that was used to generate the assets. + +It has 2 formats. A "runtime" package that should be empty-imported in the +main package for schemas with hooks or policies (potential cyclic-import). +The second format is generated under the "ent" package, and empty-import is +not necessary (no option for cyclic-import). The second format used to keep +backwards-compatibility with previous versions of ent. +*/}} + +{{ define "runtime/ent" }} + {{ template "runtime" $ }} +{{ end }} + +{{ define "runtime/pkg" }} + {{ with extend $ "Package" "runtime" }} + {{ template "runtime" . }} + {{ end }} + {{ $module := $.ModuleInfo }} + {{ if or $module.Version $module.Sum }} + const ( + {{- with $module.Version }} + Version = "{{ . }}" // Version of ent codegen. + {{- end }} + {{- with $module.Sum }} + Sum = "{{ . }}" // Sum of ent codegen. + {{- end }} + ) + {{ end }} +{{ end }} + +{{ define "runtime" }} + +{{ template "header" . }} + +{{ $hooks := 0 }} +{{ range $n := $.Nodes }} + {{ $numHooks := $n.NumHooks }}{{ if $n.HasPolicy }}{{ $numHooks = add $numHooks 1 }}{{ end }} + {{ $hooks = add $hooks $numHooks }} +{{ end }} +{{ $rtpkg := false }}{{ if hasField $ "Scope" }}{{ $rtpkg = eq $.Scope.Package "runtime" }}{{ end }} + +{{ if $rtpkg }} {{/* 1st format - runtime/runtime.go */}} + {{ if $hooks }} + {{ template "runtime/register" $ }} + {{ else }} + // The schema-stitching logic is generated in {{ $.Config.Package }}/runtime.go + {{ end }} +{{ else }}{{/* 2nd format - ent/runtime.go */}} + {{ if not $hooks }} + {{ template "runtime/register" $ }} + {{ else }} + // The schema-stitching logic is generated in {{ $.Config.Package }}/runtime/runtime.go + {{ end }} +{{ end }} +{{ end }} + + +{{/* register schema handlers to type packages */}} +{{ define "runtime/register" }} +import ( + {{- with $.Config.Schema }} + "{{ . }}" + {{- end }} + + {{- range $n := $.Nodes }} + "{{ $.Config.Package }}/{{ $n.Package }}" + {{ end -}} + + "github.com/facebookincubator/ent" +) + + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +{{- range $n := $.Nodes }} + {{- $pkg := $n.Package }} + {{- $schema := base $.Config.Schema }} + {{- if $n.HasPolicy }} + policy := {{ $schema }}.{{ $n.Name }}{}.Policy() + {{ print $pkg ".Hooks" }}[0] = func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if err := policy.EvalWrite(ctx, m); err != nil { + return nil, err + } + return next.Mutate(ctx, m) + }) + } + {{- end }} + {{- if $n.NumHooks }} + {{ print $pkg "Hooks" }} := {{ $schema }}.{{ $n.Name }}{}.Hooks() + for i, h := range {{ print $pkg "Hooks" }} { + {{ print $pkg ".Hooks" }}[i{{ if $n.HasPolicy }}+1{{ end }}] = h + } + {{- end }} + {{- if or $n.HasDefault $n.HasValidators }} + {{- with $n.MixedInWithDefaultOrValidator }} + {{ $pkg }}Mixin := {{ $schema }}.{{ $n.Name }}{}.Mixin() + {{ $pkg }}MixinFields := [...][]ent.Field{ + {{- range $i, $_ := xrange $n.NumMixin }} + {{ $pkg }}Mixin[{{ $i }}].Fields(), + {{- end }} + } + {{- end }} + {{- with $n.Fields }} + {{ $pkg }}Fields := {{ $schema }}.{{ $n.Name }}{}.Fields() + {{- end }} + {{- range $i, $f := $n.Fields }} + {{- $desc := print $pkg "Desc" $f.StructField }} + {{- /* enum default values handled near their declarations (in type package). */}} + {{- if or (and $f.Default (not $f.IsEnum)) $f.UpdateDefault $f.Validators }} + {{- if $f.Position.MixedIn }} + // {{ $desc }} is the schema descriptor for {{ $f.Name }} field. + {{ $desc }} := {{ $pkg }}MixinFields[{{ $f.Position.MixinIndex }}][{{ $f.Position.Index }}].Descriptor() + {{- else }} + // {{ $desc }} is the schema descriptor for {{ $f.Name }} field. + {{ $desc }} := {{ $pkg }}Fields[{{ $f.Position.Index }}].Descriptor() + {{- end }} + {{- end }} + {{- if and $f.Default (not $f.IsEnum) }} + {{- $default := print $pkg "." $f.DefaultName }} + // {{ $default }} holds the default value on creation for the {{ $f.Name }} field. + {{ $default }} = {{ $desc }}.Default.({{ if or $f.IsTime $f.IsUUID }}func() {{ end }}{{ $f.Type }}) + {{- end }} + {{- if $f.UpdateDefault }} + {{- $default := print $pkg "." $f.UpdateDefaultName }} + // {{ $default }} holds the default value on update for the {{ $f.Name }} field. + {{ $default }} = {{ $desc }}.UpdateDefault.({{ if $f.IsTime }}func() {{ end }}{{ $f.Type }}) + {{- end }} + {{- with $f.Validators }} + {{- $name := print $pkg "." $f.Validator }} + {{- $type := printf "func (%s) error" $f.Type }} + // {{ $name }} is a validator for the "{{ $f.Name }}" field. It is called by the builders before save. + {{- if eq $f.Validators 1 }} + {{ $name }} = {{ $desc }}.Validators[0].({{ $type }}) + {{- else }} + {{ $name }} = func() {{ $type }} { + validators := {{ $desc }}.Validators + fns := [...]func({{ $f.Type }}) error { + {{- range $j, $n := xrange $f.Validators }} + validators[{{ $j }}].(func({{ $f.Type }}) error), + {{- end }} + } + return func({{ $f.BuilderField }} {{ $f.Type }}) error { + for _, fn := range fns { + if err := fn({{ $f.BuilderField }}); err != nil { + return err + } + } + return nil + } + }() + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +} + +{{ end }} diff --git a/entc/gen/template/tx.tmpl b/entc/gen/template/tx.tmpl index 56a5def73..70294b033 100644 --- a/entc/gen/template/tx.tmpl +++ b/entc/gen/template/tx.tmpl @@ -36,15 +36,15 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - {{- if $.SupportMigrate }} - Schema: migrate.NewSchema(tx.driver), - {{- end }} - {{ range $_, $n := $.Nodes -}} - {{ $n.Name }}: New{{ $n.Name }}Client(tx.config), - {{ end -}} - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + {{ range $_, $n := $.Nodes -}} + tx.{{ $n.Name }} = New{{ $n.Name }}Client(tx.config) + {{ end -}} } {{/* first node for doc example */}} diff --git a/entc/gen/type.go b/entc/gen/type.go index 36528acba..b0ff135ab 100644 --- a/entc/gen/type.go +++ b/entc/gen/type.go @@ -7,11 +7,15 @@ package gen import ( "fmt" "go/token" + "path" "reflect" "sort" + "strconv" "strings" "unicode" + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/dialect/sql/schema" "github.com/facebookincubator/ent/entc/load" "github.com/facebookincubator/ent/schema/field" @@ -37,7 +41,7 @@ type ( Indexes []*Index // ForeignKeys are the foreign-keys that resides in the type table. ForeignKeys []*ForeignKey - foreignkeys map[string]*ForeignKey + foreignKeys map[string]struct{} } // Field holds the information of a type field used for the templates. @@ -150,7 +154,7 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) { Name: schema.Name, Fields: make([]*Field, 0, len(schema.Fields)), fields: make(map[string]*Field, len(schema.Fields)), - foreignkeys: make(map[string]*ForeignKey), + foreignKeys: make(map[string]struct{}), } for _, f := range schema.Fields { switch { @@ -270,6 +274,16 @@ func (t Type) HasOptional() bool { return false } +// HasNumeric reports if this type has a numeric field. +func (t Type) HasNumeric() bool { + for _, f := range t.Fields { + if f.Type.Numeric() { + return true + } + } + return false +} + // FKEdges returns all edges that reside on the type table as foreign-keys. func (t Type) FKEdges() (edges []*Edge) { for _, e := range t.Edges { @@ -440,10 +454,10 @@ func (t *Type) resolveFKs() { // AddForeignKey adds a foreign-key for the type if it doesn't exist. func (t *Type) addFK(fk *ForeignKey) { - if _, ok := t.foreignkeys[fk.Field.Name]; ok { + if _, ok := t.foreignKeys[fk.Field.Name]; ok { return } - t.foreignkeys[fk.Field.Name] = fk + t.foreignKeys[fk.Field.Name] = struct{}{} t.ForeignKeys = append(t.ForeignKeys, fk) } @@ -452,8 +466,47 @@ func (t Type) QueryName() string { return pascal(t.Name) + "Query" } +// MutationName returns the struct name of the mutation builder for this type. +func (t Type) MutationName() string { + return pascal(t.Name) + "Mutation" +} + +// SiblingImports returns all sibling packages that are needed for the different builders. +func (t Type) SiblingImports() []string { + var ( + paths = []string{path.Join(t.Config.Package, t.Package())} + seen = map[string]bool{paths[0]: true} + ) + for _, e := range t.Edges { + name := path.Join(t.Config.Package, e.Type.Package()) + if !seen[name] { + seen[name] = true + paths = append(paths, name) + } + } + return paths +} + +// NumHooks returns the number of hooks declared in the type schema. +func (t Type) NumHooks() int { + if t.schema != nil { + return t.schema.Hooks + } + return 0 +} + +// HasPolicy returns whether a privacy policy was declared in the type schema. +func (t Type) HasPolicy() bool { + if t.schema != nil { + return t.schema.Policy + } + return false +} + // Constant returns the constant name of the field. -func (f Field) Constant() string { return "Field" + pascal(f.Name) } +func (f Field) Constant() string { + return "Field" + pascal(f.Name) +} // DefaultName returns the variable name of the default value of this field. func (f Field) DefaultName() string { return "Default" + pascal(f.Name) } @@ -490,6 +543,27 @@ func (f Field) EnumName(enum string) string { // Validator returns the validator name. func (f Field) Validator() string { return pascal(f.Name) + "Validator" } +// mutMethods returns the method names of mutation interface. +var mutMethods = func() map[string]struct{} { + t := reflect.TypeOf(new(ent.Mutation)).Elem() + names := make(map[string]struct{}) + for i := 0; i < t.NumMethod(); i++ { + names[t.Method(i).Name] = struct{}{} + } + return names +}() + +// MutationGet returns the method name for getting the field value. +// The default name is just a pascal format. If the the method conflicts +// with the mutation methods, prefix the method with "Get". +func (f Field) MutationGet() string { + name := pascal(f.Name) + if _, ok := mutMethods[name]; ok { + name = "Get" + name + } + return name +} + // IsTime returns true if the field is a timestamp field. func (f Field) IsTime() bool { return f.Type != nil && f.Type.Type == field.TypeTime } @@ -563,8 +637,13 @@ func (f Field) Column() *schema.Column { if f.def != nil && f.def.Size != nil { c.Size = *f.def.Size } - if f.Default && !f.IsTime() { - c.Default = f.DefaultName() + switch { + case f.Default && (f.Type.Numeric() || f.Type.Type == field.TypeBool): + c.Default = f.DefaultValue() + case f.Default && (f.IsString() || f.IsEnum()): + if s, ok := f.DefaultValue().(string); ok { + c.Default = strconv.Quote(s) + } } return c } @@ -607,6 +686,11 @@ func (e Edge) Label() string { return fmt.Sprintf("%s_%s", e.Owner.Label(), snake(e.Name)) } +// Constant returns the constant name of the edge. +func (e Edge) Constant() string { + return "Edge" + pascal(e.Name) +} + // M2M indicates if this edge is M2M edge. func (e Edge) M2M() bool { return e.Rel.Type == M2M } @@ -622,9 +706,9 @@ func (e Edge) O2O() bool { return e.Rel.Type == O2O } // IsInverse returns if this edge is an inverse edge. func (e Edge) IsInverse() bool { return e.Inverse != "" } -// Constant returns the constant name of the edge. +// Constant returns the constant name of the edge for the gremlin dialect. // If the edge is inverse, it returns the constant name of the owner-edge (assoc-edge). -func (e Edge) Constant() string { +func (e Edge) LabelConstant() string { name := e.Name if e.IsInverse() { name = e.Inverse @@ -633,7 +717,7 @@ func (e Edge) Constant() string { } // InverseConstant returns the inverse constant name of the edge. -func (e Edge) InverseConstant() string { return pascal(e.Name) + "InverseLabel" } +func (e Edge) InverseLabelConstant() string { return pascal(e.Name) + "InverseLabel" } // TableConstant returns the constant name of the relation table. func (e Edge) TableConstant() string { return pascal(e.Name) + "Table" } diff --git a/entc/gen/type_test.go b/entc/gen/type_test.go index 6f08a92b3..4327fef96 100644 --- a/entc/gen/type_test.go +++ b/entc/gen/type_test.go @@ -269,10 +269,10 @@ func TestEdge(t *testing.T) { require.True(t, users.IsInverse()) require.False(t, groups.IsInverse()) - require.Equal(t, "GroupsLabel", users.Constant()) - require.Equal(t, "GroupsLabel", groups.Constant()) + require.Equal(t, "GroupsLabel", users.LabelConstant()) + require.Equal(t, "GroupsLabel", groups.LabelConstant()) - require.Equal(t, "UsersInverseLabel", users.InverseConstant()) + require.Equal(t, "UsersInverseLabel", users.InverseLabelConstant()) require.Equal(t, "user_groups", users.Label()) require.Equal(t, "user_groups", groups.Label()) } diff --git a/entc/integration/config/ent/client.go b/entc/integration/config/ent/client.go index 2efb7b267..4e94f4bc7 100644 --- a/entc/integration/config/ent/client.go +++ b/entc/integration/config/ent/client.go @@ -30,13 +30,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -64,7 +67,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -82,12 +85,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -95,6 +96,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -105,14 +112,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -122,12 +137,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -137,7 +155,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -158,3 +179,8 @@ func (c *UserClient) GetX(ctx context.Context, id int) *User { } return u } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/config/ent/config.go b/entc/integration/config/ent/config.go index dd64c4cf6..379610598 100644 --- a/entc/integration/config/ent/config.go +++ b/entc/integration/config/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/config/ent/ent.go b/entc/integration/config/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/entc/integration/config/ent/ent.go +++ b/entc/integration/config/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/config/ent/hook/hook.go b/entc/integration/config/ent/hook/hook.go new file mode 100644 index 000000000..595de2382 --- /dev/null +++ b/entc/integration/config/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/config/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/config/ent/mutation.go b/entc/integration/config/ent/mutation.go new file mode 100644 index 000000000..c18db0cfd --- /dev/null +++ b/entc/integration/config/ent/mutation.go @@ -0,0 +1,220 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/config/ent/privacy/privacy.go b/entc/integration/config/ent/privacy/privacy.go new file mode 100644 index 000000000..978a7e8ca --- /dev/null +++ b/entc/integration/config/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/config/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/config/ent/runtime.go b/entc/integration/config/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/entc/integration/config/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/entc/integration/config/ent/runtime/runtime.go b/entc/integration/config/ent/runtime/runtime.go new file mode 100644 index 000000000..29df42efb --- /dev/null +++ b/entc/integration/config/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/config/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/config/ent/tx.go b/entc/integration/config/ent/tx.go index c0c7b35ae..fe30afd5c 100644 --- a/entc/integration/config/ent/tx.go +++ b/entc/integration/config/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/config/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/config/ent/user_create.go b/entc/integration/config/ent/user_create.go index 4052fcc87..5405d2cb6 100644 --- a/entc/integration/config/ent/user_create.go +++ b/entc/integration/config/ent/user_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/config/ent/user" @@ -17,11 +18,36 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config + mutation *UserMutation + hooks []Hook } // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. diff --git a/entc/integration/config/ent/user_delete.go b/entc/integration/config/ent/user_delete.go index 3b0f710b8..8a3acd204 100644 --- a/entc/integration/config/ent/user_delete.go +++ b/entc/integration/config/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/config/ent/user_update.go b/entc/integration/config/ent/user_update.go index 4173558ea..0e7e57b16 100644 --- a/entc/integration/config/ent/user_update.go +++ b/entc/integration/config/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -87,12 +113,36 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int + hooks []Hook + mutation *UserMutation } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -123,12 +173,16 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id u = &User{config: uuo.config} _spec.Assign = u.assignValues _spec.ScanValues = u.scanValues() diff --git a/entc/integration/customid/customid_test.go b/entc/integration/customid/customid_test.go index 8aa429292..3a16be9e2 100644 --- a/entc/integration/customid/customid_test.go +++ b/entc/integration/customid/customid_test.go @@ -17,7 +17,6 @@ import ( "github.com/facebookincubator/ent/entc/integration/customid/ent/user" "github.com/go-sql-driver/mysql" - _ "github.com/go-sql-driver/mysql" "github.com/google/uuid" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" diff --git a/entc/integration/customid/ent/blob/blob.go b/entc/integration/customid/ent/blob/blob.go index 342534123..fb49b0392 100644 --- a/entc/integration/customid/ent/blob/blob.go +++ b/entc/integration/customid/ent/blob/blob.go @@ -7,7 +7,6 @@ package blob import ( - "github.com/facebookincubator/ent/entc/integration/customid/ent/schema" "github.com/google/uuid" ) @@ -15,10 +14,14 @@ const ( // Label holds the string label denoting the blob type in the database. Label = "blob" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldUUID holds the string denoting the uuid vertex property in the database. + FieldID = "id" // FieldUUID holds the string denoting the uuid vertex property in the database. FieldUUID = "uuid" + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" + // EdgeLinks holds the string denoting the links edge name in mutations. + EdgeLinks = "links" + // Table holds the table name of the blob in the database. Table = "blobs" // ParentTable is the table the holds the parent relation/edge. @@ -47,10 +50,6 @@ var ( ) var ( - fields = schema.Blob{}.Fields() - - // descUUID is the schema descriptor for uuid field. - descUUID = fields[1].Descriptor() // DefaultUUID holds the default value on creation for the uuid field. - DefaultUUID = descUUID.Default.(func() uuid.UUID) + DefaultUUID func() uuid.UUID ) diff --git a/entc/integration/customid/ent/blob_create.go b/entc/integration/customid/ent/blob_create.go index a411b4c61..67d6e42e5 100644 --- a/entc/integration/customid/ent/blob_create.go +++ b/entc/integration/customid/ent/blob_create.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/customid/ent/blob" @@ -19,30 +19,25 @@ import ( // BlobCreate is the builder for creating a Blob entity. type BlobCreate struct { config - id *uuid.UUID - uuid *uuid.UUID - parent map[uuid.UUID]struct{} - links map[uuid.UUID]struct{} + mutation *BlobMutation + hooks []Hook } // SetUUID sets the uuid field. func (bc *BlobCreate) SetUUID(u uuid.UUID) *BlobCreate { - bc.uuid = &u + bc.mutation.SetUUID(u) return bc } // SetID sets the id field. func (bc *BlobCreate) SetID(u uuid.UUID) *BlobCreate { - bc.id = &u + bc.mutation.SetID(u) return bc } // SetParentID sets the parent edge to Blob by id. func (bc *BlobCreate) SetParentID(id uuid.UUID) *BlobCreate { - if bc.parent == nil { - bc.parent = make(map[uuid.UUID]struct{}) - } - bc.parent[id] = struct{}{} + bc.mutation.SetParentID(id) return bc } @@ -61,12 +56,7 @@ func (bc *BlobCreate) SetParent(b *Blob) *BlobCreate { // AddLinkIDs adds the links edge to Blob by ids. func (bc *BlobCreate) AddLinkIDs(ids ...uuid.UUID) *BlobCreate { - if bc.links == nil { - bc.links = make(map[uuid.UUID]struct{}) - } - for i := range ids { - bc.links[ids[i]] = struct{}{} - } + bc.mutation.AddLinkIDs(ids...) return bc } @@ -81,14 +71,34 @@ func (bc *BlobCreate) AddLinks(b ...*Blob) *BlobCreate { // Save creates the Blob in the database. func (bc *BlobCreate) Save(ctx context.Context) (*Blob, error) { - if bc.uuid == nil { + if _, ok := bc.mutation.UUID(); !ok { v := blob.DefaultUUID() - bc.uuid = &v + bc.mutation.SetUUID(v) } - if len(bc.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") + var ( + err error + node *Blob + ) + if len(bc.hooks) == 0 { + node, err = bc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*BlobMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + bc.mutation = mutation + node, err = bc.sqlSave(ctx) + return node, err + }) + for i := len(bc.hooks); i > 0; i-- { + mut = bc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, bc.mutation); err != nil { + return nil, err + } } - return bc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -111,19 +121,19 @@ func (bc *BlobCreate) sqlSave(ctx context.Context) (*Blob, error) { }, } ) - if value := bc.id; value != nil { - b.ID = *value - _spec.ID.Value = *value + if id, ok := bc.mutation.ID(); ok { + b.ID = id + _spec.ID.Value = id } - if value := bc.uuid; value != nil { + if value, ok := bc.mutation.UUID(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeUUID, - Value: *value, + Value: value, Column: blob.FieldUUID, }) - b.UUID = *value + b.UUID = value } - if nodes := bc.parent; len(nodes) > 0 { + if nodes := bc.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -137,12 +147,12 @@ func (bc *BlobCreate) sqlSave(ctx context.Context) (*Blob, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := bc.links; len(nodes) > 0 { + if nodes := bc.mutation.LinksIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -156,7 +166,7 @@ func (bc *BlobCreate) sqlSave(ctx context.Context) (*Blob, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/customid/ent/blob_delete.go b/entc/integration/customid/ent/blob_delete.go index acdbf1fe0..83d10d57f 100644 --- a/entc/integration/customid/ent/blob_delete.go +++ b/entc/integration/customid/ent/blob_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // BlobDelete is the builder for deleting a Blob entity. type BlobDelete struct { config + hooks []Hook + mutation *BlobMutation predicates []predicate.Blob } @@ -30,7 +33,30 @@ func (bd *BlobDelete) Where(ps ...predicate.Blob) *BlobDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (bd *BlobDelete) Exec(ctx context.Context) (int, error) { - return bd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(bd.hooks) == 0 { + affected, err = bd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*BlobMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + bd.mutation = mutation + affected, err = bd.sqlExec(ctx) + return affected, err + }) + for i := len(bd.hooks); i > 0; i-- { + mut = bd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, bd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/customid/ent/blob_update.go b/entc/integration/customid/ent/blob_update.go index b6a6f7cf2..7df682734 100644 --- a/entc/integration/customid/ent/blob_update.go +++ b/entc/integration/customid/ent/blob_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,12 +21,9 @@ import ( // BlobUpdate is the builder for updating Blob entities. type BlobUpdate struct { config - uuid *uuid.UUID - parent map[uuid.UUID]struct{} - links map[uuid.UUID]struct{} - clearedParent bool - removedLinks map[uuid.UUID]struct{} - predicates []predicate.Blob + hooks []Hook + mutation *BlobMutation + predicates []predicate.Blob } // Where adds a new predicate for the builder. @@ -37,16 +34,13 @@ func (bu *BlobUpdate) Where(ps ...predicate.Blob) *BlobUpdate { // SetUUID sets the uuid field. func (bu *BlobUpdate) SetUUID(u uuid.UUID) *BlobUpdate { - bu.uuid = &u + bu.mutation.SetUUID(u) return bu } // SetParentID sets the parent edge to Blob by id. func (bu *BlobUpdate) SetParentID(id uuid.UUID) *BlobUpdate { - if bu.parent == nil { - bu.parent = make(map[uuid.UUID]struct{}) - } - bu.parent[id] = struct{}{} + bu.mutation.SetParentID(id) return bu } @@ -65,12 +59,7 @@ func (bu *BlobUpdate) SetParent(b *Blob) *BlobUpdate { // AddLinkIDs adds the links edge to Blob by ids. func (bu *BlobUpdate) AddLinkIDs(ids ...uuid.UUID) *BlobUpdate { - if bu.links == nil { - bu.links = make(map[uuid.UUID]struct{}) - } - for i := range ids { - bu.links[ids[i]] = struct{}{} - } + bu.mutation.AddLinkIDs(ids...) return bu } @@ -85,18 +74,13 @@ func (bu *BlobUpdate) AddLinks(b ...*Blob) *BlobUpdate { // ClearParent clears the parent edge to Blob. func (bu *BlobUpdate) ClearParent() *BlobUpdate { - bu.clearedParent = true + bu.mutation.ClearParent() return bu } // RemoveLinkIDs removes the links edge to Blob by ids. func (bu *BlobUpdate) RemoveLinkIDs(ids ...uuid.UUID) *BlobUpdate { - if bu.removedLinks == nil { - bu.removedLinks = make(map[uuid.UUID]struct{}) - } - for i := range ids { - bu.removedLinks[ids[i]] = struct{}{} - } + bu.mutation.RemoveLinkIDs(ids...) return bu } @@ -111,10 +95,31 @@ func (bu *BlobUpdate) RemoveLinks(b ...*Blob) *BlobUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (bu *BlobUpdate) Save(ctx context.Context) (int, error) { - if len(bu.parent) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"parent\"") + + var ( + err error + affected int + ) + if len(bu.hooks) == 0 { + affected, err = bu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*BlobMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + bu.mutation = mutation + affected, err = bu.sqlSave(ctx) + return affected, err + }) + for i := len(bu.hooks); i > 0; i-- { + mut = bu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, bu.mutation); err != nil { + return 0, err + } } - return bu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -157,14 +162,14 @@ func (bu *BlobUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := bu.uuid; value != nil { + if value, ok := bu.mutation.UUID(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUUID, - Value: *value, + Value: value, Column: blob.FieldUUID, }) } - if bu.clearedParent { + if bu.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -180,7 +185,7 @@ func (bu *BlobUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := bu.parent; len(nodes) > 0 { + if nodes := bu.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -194,12 +199,12 @@ func (bu *BlobUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := bu.removedLinks; len(nodes) > 0 { + if nodes := bu.mutation.RemovedLinksIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -213,12 +218,12 @@ func (bu *BlobUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := bu.links; len(nodes) > 0 { + if nodes := bu.mutation.LinksIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -232,7 +237,7 @@ func (bu *BlobUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -251,26 +256,19 @@ func (bu *BlobUpdate) sqlSave(ctx context.Context) (n int, err error) { // BlobUpdateOne is the builder for updating a single Blob entity. type BlobUpdateOne struct { config - id uuid.UUID - uuid *uuid.UUID - parent map[uuid.UUID]struct{} - links map[uuid.UUID]struct{} - clearedParent bool - removedLinks map[uuid.UUID]struct{} + hooks []Hook + mutation *BlobMutation } // SetUUID sets the uuid field. func (buo *BlobUpdateOne) SetUUID(u uuid.UUID) *BlobUpdateOne { - buo.uuid = &u + buo.mutation.SetUUID(u) return buo } // SetParentID sets the parent edge to Blob by id. func (buo *BlobUpdateOne) SetParentID(id uuid.UUID) *BlobUpdateOne { - if buo.parent == nil { - buo.parent = make(map[uuid.UUID]struct{}) - } - buo.parent[id] = struct{}{} + buo.mutation.SetParentID(id) return buo } @@ -289,12 +287,7 @@ func (buo *BlobUpdateOne) SetParent(b *Blob) *BlobUpdateOne { // AddLinkIDs adds the links edge to Blob by ids. func (buo *BlobUpdateOne) AddLinkIDs(ids ...uuid.UUID) *BlobUpdateOne { - if buo.links == nil { - buo.links = make(map[uuid.UUID]struct{}) - } - for i := range ids { - buo.links[ids[i]] = struct{}{} - } + buo.mutation.AddLinkIDs(ids...) return buo } @@ -309,18 +302,13 @@ func (buo *BlobUpdateOne) AddLinks(b ...*Blob) *BlobUpdateOne { // ClearParent clears the parent edge to Blob. func (buo *BlobUpdateOne) ClearParent() *BlobUpdateOne { - buo.clearedParent = true + buo.mutation.ClearParent() return buo } // RemoveLinkIDs removes the links edge to Blob by ids. func (buo *BlobUpdateOne) RemoveLinkIDs(ids ...uuid.UUID) *BlobUpdateOne { - if buo.removedLinks == nil { - buo.removedLinks = make(map[uuid.UUID]struct{}) - } - for i := range ids { - buo.removedLinks[ids[i]] = struct{}{} - } + buo.mutation.RemoveLinkIDs(ids...) return buo } @@ -335,10 +323,31 @@ func (buo *BlobUpdateOne) RemoveLinks(b ...*Blob) *BlobUpdateOne { // Save executes the query and returns the updated entity. func (buo *BlobUpdateOne) Save(ctx context.Context) (*Blob, error) { - if len(buo.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") + + var ( + err error + node *Blob + ) + if len(buo.hooks) == 0 { + node, err = buo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*BlobMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + buo.mutation = mutation + node, err = buo.sqlSave(ctx) + return node, err + }) + for i := len(buo.hooks); i > 0; i-- { + mut = buo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, buo.mutation); err != nil { + return nil, err + } } - return buo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -369,20 +378,24 @@ func (buo *BlobUpdateOne) sqlSave(ctx context.Context) (b *Blob, err error) { Table: blob.Table, Columns: blob.Columns, ID: &sqlgraph.FieldSpec{ - Value: buo.id, Type: field.TypeUUID, Column: blob.FieldID, }, }, } - if value := buo.uuid; value != nil { + id, ok := buo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Blob.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := buo.mutation.UUID(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUUID, - Value: *value, + Value: value, Column: blob.FieldUUID, }) } - if buo.clearedParent { + if buo.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -398,7 +411,7 @@ func (buo *BlobUpdateOne) sqlSave(ctx context.Context) (b *Blob, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := buo.parent; len(nodes) > 0 { + if nodes := buo.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -412,12 +425,12 @@ func (buo *BlobUpdateOne) sqlSave(ctx context.Context) (b *Blob, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := buo.removedLinks; len(nodes) > 0 { + if nodes := buo.mutation.RemovedLinksIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -431,12 +444,12 @@ func (buo *BlobUpdateOne) sqlSave(ctx context.Context) (b *Blob, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := buo.links; len(nodes) > 0 { + if nodes := buo.mutation.LinksIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -450,7 +463,7 @@ func (buo *BlobUpdateOne) sqlSave(ctx context.Context) (b *Blob, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/customid/ent/car/car.go b/entc/integration/customid/ent/car/car.go index 42f2c32d0..48bb8bd86 100644 --- a/entc/integration/customid/ent/car/car.go +++ b/entc/integration/customid/ent/car/car.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the car type in the database. Label = "car" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldModel holds the string denoting the model vertex property in the database. + FieldID = "id" // FieldModel holds the string denoting the model vertex property in the database. FieldModel = "model" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the car in the database. Table = "cars" // OwnerTable is the table the holds the owner relation/edge. diff --git a/entc/integration/customid/ent/car_create.go b/entc/integration/customid/ent/car_create.go index 4405ebe27..a705cc2a5 100644 --- a/entc/integration/customid/ent/car_create.go +++ b/entc/integration/customid/ent/car_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/customid/ent/car" @@ -19,22 +20,19 @@ import ( // CarCreate is the builder for creating a Car entity. type CarCreate struct { config - model *string - owner map[string]struct{} + mutation *CarMutation + hooks []Hook } // SetModel sets the model field. func (cc *CarCreate) SetModel(s string) *CarCreate { - cc.model = &s + cc.mutation.SetModel(s) return cc } // SetOwnerID sets the owner edge to Pet by id. func (cc *CarCreate) SetOwnerID(id string) *CarCreate { - if cc.owner == nil { - cc.owner = make(map[string]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -53,13 +51,33 @@ func (cc *CarCreate) SetOwner(p *Pet) *CarCreate { // Save creates the Car in the database. func (cc *CarCreate) Save(ctx context.Context) (*Car, error) { - if cc.model == nil { + if _, ok := cc.mutation.Model(); !ok { return nil, errors.New("ent: missing required field \"model\"") } - if len(cc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Car + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } } - return cc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -82,15 +100,15 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, } ) - if value := cc.model; value != nil { + if value, ok := cc.mutation.Model(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: car.FieldModel, }) - c.Model = *value + c.Model = value } - if nodes := cc.owner; len(nodes) > 0 { + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -104,7 +122,7 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/customid/ent/car_delete.go b/entc/integration/customid/ent/car_delete.go index cb6acfbe4..9f120793a 100644 --- a/entc/integration/customid/ent/car_delete.go +++ b/entc/integration/customid/ent/car_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CarDelete is the builder for deleting a Car entity. type CarDelete struct { config + hooks []Hook + mutation *CarMutation predicates []predicate.Car } @@ -30,7 +33,30 @@ func (cd *CarDelete) Where(ps ...predicate.Car) *CarDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CarDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/customid/ent/car_update.go b/entc/integration/customid/ent/car_update.go index 8578ee355..d0bc80b24 100644 --- a/entc/integration/customid/ent/car_update.go +++ b/entc/integration/customid/ent/car_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,10 +21,9 @@ import ( // CarUpdate is the builder for updating Car entities. type CarUpdate struct { config - model *string - owner map[string]struct{} - clearedOwner bool - predicates []predicate.Car + hooks []Hook + mutation *CarMutation + predicates []predicate.Car } // Where adds a new predicate for the builder. @@ -35,16 +34,13 @@ func (cu *CarUpdate) Where(ps ...predicate.Car) *CarUpdate { // SetModel sets the model field. func (cu *CarUpdate) SetModel(s string) *CarUpdate { - cu.model = &s + cu.mutation.SetModel(s) return cu } // SetOwnerID sets the owner edge to Pet by id. func (cu *CarUpdate) SetOwnerID(id string) *CarUpdate { - if cu.owner == nil { - cu.owner = make(map[string]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -63,16 +59,37 @@ func (cu *CarUpdate) SetOwner(p *Pet) *CarUpdate { // ClearOwner clears the owner edge to Pet. func (cu *CarUpdate) ClearOwner() *CarUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CarUpdate) Save(ctx context.Context) (int, error) { - if len(cu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } } - return cu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -115,14 +132,14 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := cu.model; value != nil { + if value, ok := cu.mutation.Model(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: car.FieldModel, }) } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -138,7 +155,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.owner; len(nodes) > 0 { + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -152,7 +169,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -171,24 +188,19 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { // CarUpdateOne is the builder for updating a single Car entity. type CarUpdateOne struct { config - id int - model *string - owner map[string]struct{} - clearedOwner bool + hooks []Hook + mutation *CarMutation } // SetModel sets the model field. func (cuo *CarUpdateOne) SetModel(s string) *CarUpdateOne { - cuo.model = &s + cuo.mutation.SetModel(s) return cuo } // SetOwnerID sets the owner edge to Pet by id. func (cuo *CarUpdateOne) SetOwnerID(id string) *CarUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[string]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -207,16 +219,37 @@ func (cuo *CarUpdateOne) SetOwner(p *Pet) *CarUpdateOne { // ClearOwner clears the owner edge to Pet. func (cuo *CarUpdateOne) ClearOwner() *CarUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // Save executes the query and returns the updated entity. func (cuo *CarUpdateOne) Save(ctx context.Context) (*Car, error) { - if len(cuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Car + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } } - return cuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -247,20 +280,24 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { Table: car.Table, Columns: car.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeInt, Column: car.FieldID, }, }, } - if value := cuo.model; value != nil { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Car.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.Model(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: car.FieldModel, }) } - if cuo.clearedOwner { + if cuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -276,7 +313,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.owner; len(nodes) > 0 { + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -290,7 +327,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/customid/ent/client.go b/entc/integration/customid/ent/client.go index 57f36a530..afca258f6 100644 --- a/entc/integration/customid/ent/client.go +++ b/entc/integration/customid/ent/client.go @@ -44,17 +44,20 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Blob: NewBlobClient(c), - Car: NewCarClient(c), - Group: NewGroupClient(c), - Pet: NewPetClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Blob = NewBlobClient(c.config) + c.Car = NewCarClient(c.config) + c.Group = NewGroupClient(c.config) + c.Pet = NewPetClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -82,7 +85,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Blob: NewBlobClient(cfg), @@ -104,16 +107,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Blob: NewBlobClient(cfg), - Car: NewCarClient(cfg), - Group: NewGroupClient(cfg), - Pet: NewPetClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -121,6 +118,16 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Blob.Use(hooks...) + c.Car.Use(hooks...) + c.Group.Use(hooks...) + c.Pet.Use(hooks...) + c.User.Use(hooks...) +} + // BlobClient is a client for the Blob schema. type BlobClient struct { config @@ -131,14 +138,22 @@ func NewBlobClient(c config) *BlobClient { return &BlobClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `blob.Hooks(f(g(h())))`. +func (c *BlobClient) Use(hooks ...Hook) { + c.hooks.Blob = append(c.hooks.Blob, hooks...) +} + // Create returns a create builder for Blob. func (c *BlobClient) Create() *BlobCreate { - return &BlobCreate{config: c.config} + mutation := newBlobMutation(c.config, OpCreate) + return &BlobCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Blob. func (c *BlobClient) Update() *BlobUpdate { - return &BlobUpdate{config: c.config} + mutation := newBlobMutation(c.config, OpUpdate) + return &BlobUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -148,12 +163,15 @@ func (c *BlobClient) UpdateOne(b *Blob) *BlobUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *BlobClient) UpdateOneID(id uuid.UUID) *BlobUpdateOne { - return &BlobUpdateOne{config: c.config, id: id} + mutation := newBlobMutation(c.config, OpUpdateOne) + mutation.id = &id + return &BlobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Blob. func (c *BlobClient) Delete() *BlobDelete { - return &BlobDelete{config: c.config} + mutation := newBlobMutation(c.config, OpDelete) + return &BlobDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -163,7 +181,10 @@ func (c *BlobClient) DeleteOne(b *Blob) *BlobDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *BlobClient) DeleteOneID(id uuid.UUID) *BlobDeleteOne { - return &BlobDeleteOne{c.Delete().Where(blob.ID(id))} + builder := c.Delete().Where(blob.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &BlobDeleteOne{builder} } // Create returns a query builder for Blob. @@ -213,6 +234,11 @@ func (c *BlobClient) QueryLinks(b *Blob) *BlobQuery { return query } +// Hooks returns the client hooks. +func (c *BlobClient) Hooks() []Hook { + return c.hooks.Blob +} + // CarClient is a client for the Car schema. type CarClient struct { config @@ -223,14 +249,22 @@ func NewCarClient(c config) *CarClient { return &CarClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `car.Hooks(f(g(h())))`. +func (c *CarClient) Use(hooks ...Hook) { + c.hooks.Car = append(c.hooks.Car, hooks...) +} + // Create returns a create builder for Car. func (c *CarClient) Create() *CarCreate { - return &CarCreate{config: c.config} + mutation := newCarMutation(c.config, OpCreate) + return &CarCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Car. func (c *CarClient) Update() *CarUpdate { - return &CarUpdate{config: c.config} + mutation := newCarMutation(c.config, OpUpdate) + return &CarUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -240,12 +274,15 @@ func (c *CarClient) UpdateOne(ca *Car) *CarUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CarClient) UpdateOneID(id int) *CarUpdateOne { - return &CarUpdateOne{config: c.config, id: id} + mutation := newCarMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CarUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Car. func (c *CarClient) Delete() *CarDelete { - return &CarDelete{config: c.config} + mutation := newCarMutation(c.config, OpDelete) + return &CarDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -255,7 +292,10 @@ func (c *CarClient) DeleteOne(ca *Car) *CarDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CarClient) DeleteOneID(id int) *CarDeleteOne { - return &CarDeleteOne{c.Delete().Where(car.ID(id))} + builder := c.Delete().Where(car.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CarDeleteOne{builder} } // Create returns a query builder for Car. @@ -291,6 +331,11 @@ func (c *CarClient) QueryOwner(ca *Car) *PetQuery { return query } +// Hooks returns the client hooks. +func (c *CarClient) Hooks() []Hook { + return c.hooks.Car +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -301,14 +346,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -318,12 +371,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id int) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -333,7 +389,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id int) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -369,6 +428,11 @@ func (c *GroupClient) QueryUsers(gr *Group) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -379,14 +443,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -396,12 +468,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id string) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -411,7 +486,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id string) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -461,6 +539,11 @@ func (c *PetClient) QueryCars(pe *Pet) *CarQuery { return query } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -471,14 +554,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -488,12 +579,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -503,7 +597,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -580,3 +677,8 @@ func (c *UserClient) QueryPets(u *User) *PetQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/customid/ent/config.go b/entc/integration/customid/ent/config.go index dd64c4cf6..f34900b67 100644 --- a/entc/integration/customid/ent/config.go +++ b/entc/integration/customid/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,17 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Blob []ent.Hook + Car []ent.Hook + Group []ent.Hook + Pet []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/customid/ent/ent.go b/entc/integration/customid/ent/ent.go index 01417b368..dd408a585 100644 --- a/entc/integration/customid/ent/ent.go +++ b/entc/integration/customid/ent/ent.go @@ -11,6 +11,7 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -18,6 +19,16 @@ import ( "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/customid/ent/group/group.go b/entc/integration/customid/ent/group/group.go index a9fef33fa..73c13c862 100644 --- a/entc/integration/customid/ent/group/group.go +++ b/entc/integration/customid/ent/group/group.go @@ -12,6 +12,9 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // Table holds the table name of the group in the database. Table = "groups" // UsersTable is the table the holds the users relation/edge. The primary key declared below. diff --git a/entc/integration/customid/ent/group_create.go b/entc/integration/customid/ent/group_create.go index ef2c56f9c..7e30f8c42 100644 --- a/entc/integration/customid/ent/group_create.go +++ b/entc/integration/customid/ent/group_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/customid/ent/group" @@ -18,24 +19,19 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - id *int - users map[int]struct{} + mutation *GroupMutation + hooks []Hook } // SetID sets the id field. func (gc *GroupCreate) SetID(i int) *GroupCreate { - gc.id = &i + gc.mutation.SetID(i) return gc } // AddUserIDs adds the users edge to User by ids. func (gc *GroupCreate) AddUserIDs(ids ...int) *GroupCreate { - if gc.users == nil { - gc.users = make(map[int]struct{}) - } - for i := range ids { - gc.users[ids[i]] = struct{}{} - } + gc.mutation.AddUserIDs(ids...) return gc } @@ -50,7 +46,30 @@ func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - return gc.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -73,11 +92,11 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, } ) - if value := gc.id; value != nil { - gr.ID = *value - _spec.ID.Value = *value + if id, ok := gc.mutation.ID(); ok { + gr.ID = id + _spec.ID.Value = id } - if nodes := gc.users; len(nodes) > 0 { + if nodes := gc.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -91,7 +110,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/customid/ent/group_delete.go b/entc/integration/customid/ent/group_delete.go index 8b5c4e249..0cdd4dcd7 100644 --- a/entc/integration/customid/ent/group_delete.go +++ b/entc/integration/customid/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/customid/ent/group_update.go b/entc/integration/customid/ent/group_update.go index 5d56a4d39..06d79def3 100644 --- a/entc/integration/customid/ent/group_update.go +++ b/entc/integration/customid/ent/group_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,9 +21,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - users map[int]struct{} - removedUsers map[int]struct{} - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -33,12 +34,7 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // AddUserIDs adds the users edge to User by ids. func (gu *GroupUpdate) AddUserIDs(ids ...int) *GroupUpdate { - if gu.users == nil { - gu.users = make(map[int]struct{}) - } - for i := range ids { - gu.users[ids[i]] = struct{}{} - } + gu.mutation.AddUserIDs(ids...) return gu } @@ -53,12 +49,7 @@ func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { // RemoveUserIDs removes the users edge to User by ids. func (gu *GroupUpdate) RemoveUserIDs(ids ...int) *GroupUpdate { - if gu.removedUsers == nil { - gu.removedUsers = make(map[int]struct{}) - } - for i := range ids { - gu.removedUsers[ids[i]] = struct{}{} - } + gu.mutation.RemoveUserIDs(ids...) return gu } @@ -73,7 +64,31 @@ func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - return gu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -116,7 +131,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if nodes := gu.removedUsers; len(nodes) > 0 { + if nodes := gu.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -130,12 +145,12 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.users; len(nodes) > 0 { + if nodes := gu.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -149,7 +164,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -168,19 +183,13 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id int - users map[int]struct{} - removedUsers map[int]struct{} + hooks []Hook + mutation *GroupMutation } // AddUserIDs adds the users edge to User by ids. func (guo *GroupUpdateOne) AddUserIDs(ids ...int) *GroupUpdateOne { - if guo.users == nil { - guo.users = make(map[int]struct{}) - } - for i := range ids { - guo.users[ids[i]] = struct{}{} - } + guo.mutation.AddUserIDs(ids...) return guo } @@ -195,12 +204,7 @@ func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { // RemoveUserIDs removes the users edge to User by ids. func (guo *GroupUpdateOne) RemoveUserIDs(ids ...int) *GroupUpdateOne { - if guo.removedUsers == nil { - guo.removedUsers = make(map[int]struct{}) - } - for i := range ids { - guo.removedUsers[ids[i]] = struct{}{} - } + guo.mutation.RemoveUserIDs(ids...) return guo } @@ -215,7 +219,31 @@ func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - return guo.sqlSave(ctx) + + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -246,13 +274,17 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeInt, Column: group.FieldID, }, }, } - if nodes := guo.removedUsers; len(nodes) > 0 { + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id + if nodes := guo.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -266,12 +298,12 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.users; len(nodes) > 0 { + if nodes := guo.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -285,7 +317,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/customid/ent/hook/hook.go b/entc/integration/customid/ent/hook/hook.go new file mode 100644 index 000000000..aad4d8d07 --- /dev/null +++ b/entc/integration/customid/ent/hook/hook.go @@ -0,0 +1,113 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent" +) + +// The BlobFunc type is an adapter to allow the use of ordinary +// function as Blob mutator. +type BlobFunc func(context.Context, *ent.BlobMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f BlobFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.BlobMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.BlobMutation", m) + } + return f(ctx, mv) +} + +// The CarFunc type is an adapter to allow the use of ordinary +// function as Car mutator. +type CarFunc func(context.Context, *ent.CarMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CarFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CarMutation", m) + } + return f(ctx, mv) +} + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/customid/ent/migrate/schema.go b/entc/integration/customid/ent/migrate/schema.go index 49c822d6e..371890e2d 100644 --- a/entc/integration/customid/ent/migrate/schema.go +++ b/entc/integration/customid/ent/migrate/schema.go @@ -7,8 +7,6 @@ package migrate import ( - "github.com/facebookincubator/ent/entc/integration/customid/ent/blob" - "github.com/facebookincubator/ent/dialect/sql/schema" "github.com/facebookincubator/ent/schema/field" ) @@ -17,7 +15,7 @@ var ( // BlobsColumns holds the columns for the "blobs" table. BlobsColumns = []*schema.Column{ {Name: "id", Type: field.TypeUUID}, - {Name: "uuid", Type: field.TypeUUID, Default: blob.DefaultUUID}, + {Name: "uuid", Type: field.TypeUUID}, {Name: "blob_parent", Type: field.TypeUUID, Unique: true, Nullable: true}, } // BlobsTable holds the schema information for the "blobs" table. diff --git a/entc/integration/customid/ent/mutation.go b/entc/integration/customid/ent/mutation.go new file mode 100644 index 000000000..dce4bda3a --- /dev/null +++ b/entc/integration/customid/ent/mutation.go @@ -0,0 +1,1740 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent/blob" + "github.com/facebookincubator/ent/entc/integration/customid/ent/car" + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" + "github.com/facebookincubator/ent/entc/integration/customid/ent/pet" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/google/uuid" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeBlob = "Blob" + TypeCar = "Car" + TypeGroup = "Group" + TypePet = "Pet" + TypeUser = "User" +) + +// BlobMutation represents an operation that mutate the Blobs +// nodes in the graph. +type BlobMutation struct { + config + op Op + typ string + id *uuid.UUID + uuid *uuid.UUID + clearedFields map[string]bool + parent *uuid.UUID + clearedparent bool + links map[uuid.UUID]struct{} + removedlinks map[uuid.UUID]struct{} +} + +var _ ent.Mutation = (*BlobMutation)(nil) + +// newBlobMutation creates new mutation for $n.Name. +func newBlobMutation(c config, op Op) *BlobMutation { + return &BlobMutation{ + config: c, + op: op, + typ: TypeBlob, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m BlobMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m BlobMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that, this +// operation is accepted only on Blob creation. +func (m *BlobMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *BlobMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetUUID sets the uuid field. +func (m *BlobMutation) SetUUID(u uuid.UUID) { + m.uuid = &u +} + +// UUID returns the uuid value in the mutation. +func (m *BlobMutation) UUID() (r uuid.UUID, exists bool) { + v := m.uuid + if v == nil { + return + } + return *v, true +} + +// ResetUUID reset all changes of the uuid field. +func (m *BlobMutation) ResetUUID() { + m.uuid = nil +} + +// SetParentID sets the parent edge to Blob by id. +func (m *BlobMutation) SetParentID(id uuid.UUID) { + m.parent = &id +} + +// ClearParent clears the parent edge to Blob. +func (m *BlobMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared returns if the edge parent was cleared. +func (m *BlobMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the parent id in the mutation. +func (m *BlobMutation) ParentID() (id uuid.UUID, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the parent ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *BlobMutation) ParentIDs() (ids []uuid.UUID) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent reset all changes of the parent edge. +func (m *BlobMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// AddLinkIDs adds the links edge to Blob by ids. +func (m *BlobMutation) AddLinkIDs(ids ...uuid.UUID) { + if m.links == nil { + m.links = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.links[ids[i]] = struct{}{} + } +} + +// RemoveLinkIDs removes the links edge to Blob by ids. +func (m *BlobMutation) RemoveLinkIDs(ids ...uuid.UUID) { + if m.removedlinks == nil { + m.removedlinks = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.removedlinks[ids[i]] = struct{}{} + } +} + +// RemovedLinks returns the removed ids of links. +func (m *BlobMutation) RemovedLinksIDs() (ids []uuid.UUID) { + for id := range m.removedlinks { + ids = append(ids, id) + } + return +} + +// LinksIDs returns the links ids in the mutation. +func (m *BlobMutation) LinksIDs() (ids []uuid.UUID) { + for id := range m.links { + ids = append(ids, id) + } + return +} + +// ResetLinks reset all changes of the links edge. +func (m *BlobMutation) ResetLinks() { + m.links = nil + m.removedlinks = nil +} + +// Op returns the operation name. +func (m *BlobMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Blob). +func (m *BlobMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *BlobMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.uuid != nil { + fields = append(fields, blob.FieldUUID) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *BlobMutation) Field(name string) (ent.Value, bool) { + switch name { + case blob.FieldUUID: + return m.UUID() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *BlobMutation) SetField(name string, value ent.Value) error { + switch name { + case blob.FieldUUID: + v, ok := value.(uuid.UUID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUUID(v) + return nil + } + return fmt.Errorf("unknown Blob field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *BlobMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *BlobMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *BlobMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Blob numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *BlobMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *BlobMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *BlobMutation) ClearField(name string) error { + return fmt.Errorf("unknown Blob nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *BlobMutation) ResetField(name string) error { + switch name { + case blob.FieldUUID: + m.ResetUUID() + return nil + } + return fmt.Errorf("unknown Blob field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *BlobMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.parent != nil { + edges = append(edges, blob.EdgeParent) + } + if m.links != nil { + edges = append(edges, blob.EdgeLinks) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *BlobMutation) AddedIDs(name string) []ent.Value { + switch name { + case blob.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + case blob.EdgeLinks: + ids := make([]ent.Value, 0, len(m.links)) + for id := range m.links { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *BlobMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedlinks != nil { + edges = append(edges, blob.EdgeLinks) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *BlobMutation) RemovedIDs(name string) []ent.Value { + switch name { + case blob.EdgeLinks: + ids := make([]ent.Value, 0, len(m.removedlinks)) + for id := range m.removedlinks { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *BlobMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedparent { + edges = append(edges, blob.EdgeParent) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *BlobMutation) EdgeCleared(name string) bool { + switch name { + case blob.EdgeParent: + return m.clearedparent + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *BlobMutation) ClearEdge(name string) error { + switch name { + case blob.EdgeParent: + m.ClearParent() + return nil + } + return fmt.Errorf("unknown Blob unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *BlobMutation) ResetEdge(name string) error { + switch name { + case blob.EdgeParent: + m.ResetParent() + return nil + case blob.EdgeLinks: + m.ResetLinks() + return nil + } + return fmt.Errorf("unknown Blob edge %s", name) +} + +// CarMutation represents an operation that mutate the Cars +// nodes in the graph. +type CarMutation struct { + config + op Op + typ string + id *int + model *string + clearedFields map[string]bool + owner *string + clearedowner bool +} + +var _ ent.Mutation = (*CarMutation)(nil) + +// newCarMutation creates new mutation for $n.Name. +func newCarMutation(c config, op Op) *CarMutation { + return &CarMutation{ + config: c, + op: op, + typ: TypeCar, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CarMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CarMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CarMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetModel sets the model field. +func (m *CarMutation) SetModel(s string) { + m.model = &s +} + +// Model returns the model value in the mutation. +func (m *CarMutation) Model() (r string, exists bool) { + v := m.model + if v == nil { + return + } + return *v, true +} + +// ResetModel reset all changes of the model field. +func (m *CarMutation) ResetModel() { + m.model = nil +} + +// SetOwnerID sets the owner edge to Pet by id. +func (m *CarMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to Pet. +func (m *CarMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CarMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CarMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CarMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CarMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *CarMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Car). +func (m *CarMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CarMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.model != nil { + fields = append(fields, car.FieldModel) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CarMutation) Field(name string) (ent.Value, bool) { + switch name { + case car.FieldModel: + return m.Model() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) SetField(name string, value ent.Value) error { + switch name { + case car.FieldModel: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetModel(v) + return nil + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CarMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CarMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Car numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CarMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CarMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CarMutation) ClearField(name string) error { + return fmt.Errorf("unknown Car nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CarMutation) ResetField(name string) error { + switch name { + case car.FieldModel: + m.ResetModel() + return nil + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CarMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CarMutation) AddedIDs(name string) []ent.Value { + switch name { + case car.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CarMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CarMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CarMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CarMutation) EdgeCleared(name string) bool { + switch name { + case car.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CarMutation) ClearEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Car unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CarMutation) ResetEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Car edge %s", name) +} + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool + users map[int]struct{} + removedusers map[int]struct{} +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that, this +// operation is accepted only on Group creation. +func (m *GroupMutation) SetID(id int) { + m.id = &id +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// AddUserIDs adds the users edge to User by ids. +func (m *GroupMutation) AddUserIDs(ids ...int) { + if m.users == nil { + m.users = make(map[int]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// RemoveUserIDs removes the users edge to User by ids. +func (m *GroupMutation) RemoveUserIDs(ids ...int) { + if m.removedusers == nil { + m.removedusers = make(map[int]struct{}) + } + for i := range ids { + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed ids of users. +func (m *GroupMutation) RemovedUsersIDs() (ids []int) { + for id := range m.removedusers { + ids = append(ids, id) + } + return +} + +// UsersIDs returns the users ids in the mutation. +func (m *GroupMutation) UsersIDs() (ids []int) { + for id := range m.users { + ids = append(ids, id) + } + return +} + +// ResetUsers reset all changes of the users edge. +func (m *GroupMutation) ResetUsers() { + m.users = nil + m.removedusers = nil +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.users != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedusers != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + case group.EdgeUsers: + m.ResetUsers() + return nil + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *string + clearedFields map[string]bool + owner *int + clearedowner bool + cars map[int]struct{} + removedcars map[int]struct{} +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that, this +// operation is accepted only on Pet creation. +func (m *PetMutation) SetID(id string) { + m.id = &id +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetOwnerID sets the owner edge to User by id. +func (m *PetMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *PetMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *PetMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *PetMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *PetMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *PetMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// AddCarIDs adds the cars edge to Car by ids. +func (m *PetMutation) AddCarIDs(ids ...int) { + if m.cars == nil { + m.cars = make(map[int]struct{}) + } + for i := range ids { + m.cars[ids[i]] = struct{}{} + } +} + +// RemoveCarIDs removes the cars edge to Car by ids. +func (m *PetMutation) RemoveCarIDs(ids ...int) { + if m.removedcars == nil { + m.removedcars = make(map[int]struct{}) + } + for i := range ids { + m.removedcars[ids[i]] = struct{}{} + } +} + +// RemovedCars returns the removed ids of cars. +func (m *PetMutation) RemovedCarsIDs() (ids []int) { + for id := range m.removedcars { + ids = append(ids, id) + } + return +} + +// CarsIDs returns the cars ids in the mutation. +func (m *PetMutation) CarsIDs() (ids []int) { + for id := range m.cars { + ids = append(ids, id) + } + return +} + +// ResetCars reset all changes of the cars edge. +func (m *PetMutation) ResetCars() { + m.cars = nil + m.removedcars = nil +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.owner != nil { + edges = append(edges, pet.EdgeOwner) + } + if m.cars != nil { + edges = append(edges, pet.EdgeCars) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + case pet.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + case pet.EdgeCars: + ids := make([]ent.Value, 0, len(m.cars)) + for id := range m.cars { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedcars != nil { + edges = append(edges, pet.EdgeCars) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + case pet.EdgeCars: + ids := make([]ent.Value, 0, len(m.removedcars)) + for id := range m.removedcars { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedowner { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + case pet.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ResetOwner() + return nil + case pet.EdgeCars: + m.ResetCars() + return nil + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool + groups map[int]struct{} + removedgroups map[int]struct{} + parent *int + clearedparent bool + children map[int]struct{} + removedchildren map[int]struct{} + pets map[string]struct{} + removedpets map[string]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that, this +// operation is accepted only on User creation. +func (m *UserMutation) SetID(id int) { + m.id = &id +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *UserMutation) AddGroupIDs(ids ...int) { + if m.groups == nil { + m.groups = make(map[int]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *UserMutation) RemoveGroupIDs(ids ...int) { + if m.removedgroups == nil { + m.removedgroups = make(map[int]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *UserMutation) RemovedGroupsIDs() (ids []int) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *UserMutation) GroupsIDs() (ids []int) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *UserMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// SetParentID sets the parent edge to User by id. +func (m *UserMutation) SetParentID(id int) { + m.parent = &id +} + +// ClearParent clears the parent edge to User. +func (m *UserMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared returns if the edge parent was cleared. +func (m *UserMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the parent id in the mutation. +func (m *UserMutation) ParentID() (id int, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the parent ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *UserMutation) ParentIDs() (ids []int) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent reset all changes of the parent edge. +func (m *UserMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// AddChildIDs adds the children edge to User by ids. +func (m *UserMutation) AddChildIDs(ids ...int) { + if m.children == nil { + m.children = make(map[int]struct{}) + } + for i := range ids { + m.children[ids[i]] = struct{}{} + } +} + +// RemoveChildIDs removes the children edge to User by ids. +func (m *UserMutation) RemoveChildIDs(ids ...int) { + if m.removedchildren == nil { + m.removedchildren = make(map[int]struct{}) + } + for i := range ids { + m.removedchildren[ids[i]] = struct{}{} + } +} + +// RemovedChildren returns the removed ids of children. +func (m *UserMutation) RemovedChildrenIDs() (ids []int) { + for id := range m.removedchildren { + ids = append(ids, id) + } + return +} + +// ChildrenIDs returns the children ids in the mutation. +func (m *UserMutation) ChildrenIDs() (ids []int) { + for id := range m.children { + ids = append(ids, id) + } + return +} + +// ResetChildren reset all changes of the children edge. +func (m *UserMutation) ResetChildren() { + m.children = nil + m.removedchildren = nil +} + +// AddPetIDs adds the pets edge to Pet by ids. +func (m *UserMutation) AddPetIDs(ids ...string) { + if m.pets == nil { + m.pets = make(map[string]struct{}) + } + for i := range ids { + m.pets[ids[i]] = struct{}{} + } +} + +// RemovePetIDs removes the pets edge to Pet by ids. +func (m *UserMutation) RemovePetIDs(ids ...string) { + if m.removedpets == nil { + m.removedpets = make(map[string]struct{}) + } + for i := range ids { + m.removedpets[ids[i]] = struct{}{} + } +} + +// RemovedPets returns the removed ids of pets. +func (m *UserMutation) RemovedPetsIDs() (ids []string) { + for id := range m.removedpets { + ids = append(ids, id) + } + return +} + +// PetsIDs returns the pets ids in the mutation. +func (m *UserMutation) PetsIDs() (ids []string) { + for id := range m.pets { + ids = append(ids, id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.removedpets = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 4) + if m.groups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.parent != nil { + edges = append(edges, user.EdgeParent) + } + if m.children != nil { + edges = append(edges, user.EdgeChildren) + } + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + case user.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.children)) + for id := range m.children { + ids = append(ids, id) + } + return ids + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.pets)) + for id := range m.pets { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 4) + if m.removedgroups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.removedchildren != nil { + edges = append(edges, user.EdgeChildren) + } + if m.removedpets != nil { + edges = append(edges, user.EdgePets) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.removedchildren)) + for id := range m.removedchildren { + ids = append(ids, id) + } + return ids + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.removedpets)) + for id := range m.removedpets { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 4) + if m.clearedparent { + edges = append(edges, user.EdgeParent) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeParent: + return m.clearedparent + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeParent: + m.ClearParent() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeGroups: + m.ResetGroups() + return nil + case user.EdgeParent: + m.ResetParent() + return nil + case user.EdgeChildren: + m.ResetChildren() + return nil + case user.EdgePets: + m.ResetPets() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/customid/ent/pet/pet.go b/entc/integration/customid/ent/pet/pet.go index 68840edba..d53111d34 100644 --- a/entc/integration/customid/ent/pet/pet.go +++ b/entc/integration/customid/ent/pet/pet.go @@ -12,6 +12,11 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // EdgeCars holds the string denoting the cars edge name in mutations. + EdgeCars = "cars" + // Table holds the table name of the pet in the database. Table = "pets" // OwnerTable is the table the holds the owner relation/edge. diff --git a/entc/integration/customid/ent/pet_create.go b/entc/integration/customid/ent/pet_create.go index 54f79f3ec..784200cd8 100644 --- a/entc/integration/customid/ent/pet_create.go +++ b/entc/integration/customid/ent/pet_create.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/customid/ent/car" @@ -20,23 +20,19 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - id *string - owner map[int]struct{} - cars map[int]struct{} + mutation *PetMutation + hooks []Hook } // SetID sets the id field. func (pc *PetCreate) SetID(s string) *PetCreate { - pc.id = &s + pc.mutation.SetID(s) return pc } // SetOwnerID sets the owner edge to User by id. func (pc *PetCreate) SetOwnerID(id int) *PetCreate { - if pc.owner == nil { - pc.owner = make(map[int]struct{}) - } - pc.owner[id] = struct{}{} + pc.mutation.SetOwnerID(id) return pc } @@ -55,12 +51,7 @@ func (pc *PetCreate) SetOwner(u *User) *PetCreate { // AddCarIDs adds the cars edge to Car by ids. func (pc *PetCreate) AddCarIDs(ids ...int) *PetCreate { - if pc.cars == nil { - pc.cars = make(map[int]struct{}) - } - for i := range ids { - pc.cars[ids[i]] = struct{}{} - } + pc.mutation.AddCarIDs(ids...) return pc } @@ -75,10 +66,30 @@ func (pc *PetCreate) AddCars(c ...*Car) *PetCreate { // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - if len(pc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } } - return pc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -101,11 +112,11 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, } ) - if value := pc.id; value != nil { - pe.ID = *value - _spec.ID.Value = *value + if id, ok := pc.mutation.ID(); ok { + pe.ID = id + _spec.ID.Value = id } - if nodes := pc.owner; len(nodes) > 0 { + if nodes := pc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -119,12 +130,12 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := pc.cars; len(nodes) > 0 { + if nodes := pc.mutation.CarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -138,7 +149,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/customid/ent/pet_delete.go b/entc/integration/customid/ent/pet_delete.go index a2240589b..0712828d0 100644 --- a/entc/integration/customid/ent/pet_delete.go +++ b/entc/integration/customid/ent/pet_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/customid/ent/pet_update.go b/entc/integration/customid/ent/pet_update.go index 8b01f26fa..8cffb13d2 100644 --- a/entc/integration/customid/ent/pet_update.go +++ b/entc/integration/customid/ent/pet_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -22,11 +22,9 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - owner map[int]struct{} - cars map[int]struct{} - clearedOwner bool - removedCars map[int]struct{} - predicates []predicate.Pet + hooks []Hook + mutation *PetMutation + predicates []predicate.Pet } // Where adds a new predicate for the builder. @@ -37,10 +35,7 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // SetOwnerID sets the owner edge to User by id. func (pu *PetUpdate) SetOwnerID(id int) *PetUpdate { - if pu.owner == nil { - pu.owner = make(map[int]struct{}) - } - pu.owner[id] = struct{}{} + pu.mutation.SetOwnerID(id) return pu } @@ -59,12 +54,7 @@ func (pu *PetUpdate) SetOwner(u *User) *PetUpdate { // AddCarIDs adds the cars edge to Car by ids. func (pu *PetUpdate) AddCarIDs(ids ...int) *PetUpdate { - if pu.cars == nil { - pu.cars = make(map[int]struct{}) - } - for i := range ids { - pu.cars[ids[i]] = struct{}{} - } + pu.mutation.AddCarIDs(ids...) return pu } @@ -79,18 +69,13 @@ func (pu *PetUpdate) AddCars(c ...*Car) *PetUpdate { // ClearOwner clears the owner edge to User. func (pu *PetUpdate) ClearOwner() *PetUpdate { - pu.clearedOwner = true + pu.mutation.ClearOwner() return pu } // RemoveCarIDs removes the cars edge to Car by ids. func (pu *PetUpdate) RemoveCarIDs(ids ...int) *PetUpdate { - if pu.removedCars == nil { - pu.removedCars = make(map[int]struct{}) - } - for i := range ids { - pu.removedCars[ids[i]] = struct{}{} - } + pu.mutation.RemoveCarIDs(ids...) return pu } @@ -105,10 +90,31 @@ func (pu *PetUpdate) RemoveCars(c ...*Car) *PetUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - if len(pu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } } - return pu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -151,7 +157,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if pu.clearedOwner { + if pu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -167,7 +173,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.owner; len(nodes) > 0 { + if nodes := pu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -181,12 +187,12 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := pu.removedCars; len(nodes) > 0 { + if nodes := pu.mutation.RemovedCarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -200,12 +206,12 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.cars; len(nodes) > 0 { + if nodes := pu.mutation.CarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -219,7 +225,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -238,19 +244,13 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id string - owner map[int]struct{} - cars map[int]struct{} - clearedOwner bool - removedCars map[int]struct{} + hooks []Hook + mutation *PetMutation } // SetOwnerID sets the owner edge to User by id. func (puo *PetUpdateOne) SetOwnerID(id int) *PetUpdateOne { - if puo.owner == nil { - puo.owner = make(map[int]struct{}) - } - puo.owner[id] = struct{}{} + puo.mutation.SetOwnerID(id) return puo } @@ -269,12 +269,7 @@ func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne { // AddCarIDs adds the cars edge to Car by ids. func (puo *PetUpdateOne) AddCarIDs(ids ...int) *PetUpdateOne { - if puo.cars == nil { - puo.cars = make(map[int]struct{}) - } - for i := range ids { - puo.cars[ids[i]] = struct{}{} - } + puo.mutation.AddCarIDs(ids...) return puo } @@ -289,18 +284,13 @@ func (puo *PetUpdateOne) AddCars(c ...*Car) *PetUpdateOne { // ClearOwner clears the owner edge to User. func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne { - puo.clearedOwner = true + puo.mutation.ClearOwner() return puo } // RemoveCarIDs removes the cars edge to Car by ids. func (puo *PetUpdateOne) RemoveCarIDs(ids ...int) *PetUpdateOne { - if puo.removedCars == nil { - puo.removedCars = make(map[int]struct{}) - } - for i := range ids { - puo.removedCars[ids[i]] = struct{}{} - } + puo.mutation.RemoveCarIDs(ids...) return puo } @@ -315,10 +305,31 @@ func (puo *PetUpdateOne) RemoveCars(c ...*Car) *PetUpdateOne { // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - if len(puo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } } - return puo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -349,13 +360,17 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { Table: pet.Table, Columns: pet.Columns, ID: &sqlgraph.FieldSpec{ - Value: puo.id, Type: field.TypeString, Column: pet.FieldID, }, }, } - if puo.clearedOwner { + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + _spec.Node.ID.Value = id + if puo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -371,7 +386,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.owner; len(nodes) > 0 { + if nodes := puo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -385,12 +400,12 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := puo.removedCars; len(nodes) > 0 { + if nodes := puo.mutation.RemovedCarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -404,12 +419,12 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.cars; len(nodes) > 0 { + if nodes := puo.mutation.CarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -423,7 +438,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/customid/ent/privacy/privacy.go b/entc/integration/customid/ent/privacy/privacy.go new file mode 100644 index 000000000..0d4440c0f --- /dev/null +++ b/entc/integration/customid/ent/privacy/privacy.go @@ -0,0 +1,267 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The BlobReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type BlobReadRuleFunc func(context.Context, *ent.Blob) error + +// EvalRead calls f(ctx, v). +func (f BlobReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Blob); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Blob", v) +} + +// The BlobWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type BlobWriteRuleFunc func(context.Context, *ent.BlobMutation) error + +// EvalWrite calls f(ctx, m). +func (f BlobWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.BlobMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.BlobMutation", m) +} + +// The CarReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CarReadRuleFunc func(context.Context, *ent.Car) error + +// EvalRead calls f(ctx, v). +func (f CarReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Car); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Car", v) +} + +// The CarWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CarWriteRuleFunc func(context.Context, *ent.CarMutation) error + +// EvalWrite calls f(ctx, m). +func (f CarWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CarMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CarMutation", m) +} + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/customid/ent/runtime.go b/entc/integration/customid/ent/runtime.go new file mode 100644 index 000000000..c317ffeb6 --- /dev/null +++ b/entc/integration/customid/ent/runtime.go @@ -0,0 +1,24 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "github.com/facebookincubator/ent/entc/integration/customid/ent/blob" + "github.com/facebookincubator/ent/entc/integration/customid/ent/schema" + "github.com/google/uuid" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + blobFields := schema.Blob{}.Fields() + // blobDescUUID is the schema descriptor for uuid field. + blobDescUUID := blobFields[1].Descriptor() + // blob.DefaultUUID holds the default value on creation for the uuid field. + blob.DefaultUUID = blobDescUUID.Default.(func() uuid.UUID) +} diff --git a/entc/integration/customid/ent/runtime/runtime.go b/entc/integration/customid/ent/runtime/runtime.go new file mode 100644 index 000000000..19727b625 --- /dev/null +++ b/entc/integration/customid/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/customid/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/customid/ent/tx.go b/entc/integration/customid/ent/tx.go index 86b97a0c9..bfac47915 100644 --- a/entc/integration/customid/ent/tx.go +++ b/entc/integration/customid/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/customid/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -40,15 +39,17 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Blob: NewBlobClient(tx.config), - Car: NewCarClient(tx.config), - Group: NewGroupClient(tx.config), - Pet: NewPetClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Blob = NewBlobClient(tx.config) + tx.Car = NewCarClient(tx.config) + tx.Group = NewGroupClient(tx.config) + tx.Pet = NewPetClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/customid/ent/user/user.go b/entc/integration/customid/ent/user/user.go index a22c8918e..5d98d5a68 100644 --- a/entc/integration/customid/ent/user/user.go +++ b/entc/integration/customid/ent/user/user.go @@ -12,6 +12,15 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" + // EdgeChildren holds the string denoting the children edge name in mutations. + EdgeChildren = "children" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" + // Table holds the table name of the user in the database. Table = "users" // GroupsTable is the table the holds the groups relation/edge. The primary key declared below. diff --git a/entc/integration/customid/ent/user_create.go b/entc/integration/customid/ent/user_create.go index 8272b855f..55994ea04 100644 --- a/entc/integration/customid/ent/user_create.go +++ b/entc/integration/customid/ent/user_create.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/customid/ent/group" @@ -20,27 +20,19 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - id *int - groups map[int]struct{} - parent map[int]struct{} - children map[int]struct{} - pets map[string]struct{} + mutation *UserMutation + hooks []Hook } // SetID sets the id field. func (uc *UserCreate) SetID(i int) *UserCreate { - uc.id = &i + uc.mutation.SetID(i) return uc } // AddGroupIDs adds the groups edge to Group by ids. func (uc *UserCreate) AddGroupIDs(ids ...int) *UserCreate { - if uc.groups == nil { - uc.groups = make(map[int]struct{}) - } - for i := range ids { - uc.groups[ids[i]] = struct{}{} - } + uc.mutation.AddGroupIDs(ids...) return uc } @@ -55,10 +47,7 @@ func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { // SetParentID sets the parent edge to User by id. func (uc *UserCreate) SetParentID(id int) *UserCreate { - if uc.parent == nil { - uc.parent = make(map[int]struct{}) - } - uc.parent[id] = struct{}{} + uc.mutation.SetParentID(id) return uc } @@ -77,12 +66,7 @@ func (uc *UserCreate) SetParent(u *User) *UserCreate { // AddChildIDs adds the children edge to User by ids. func (uc *UserCreate) AddChildIDs(ids ...int) *UserCreate { - if uc.children == nil { - uc.children = make(map[int]struct{}) - } - for i := range ids { - uc.children[ids[i]] = struct{}{} - } + uc.mutation.AddChildIDs(ids...) return uc } @@ -97,12 +81,7 @@ func (uc *UserCreate) AddChildren(u ...*User) *UserCreate { // AddPetIDs adds the pets edge to Pet by ids. func (uc *UserCreate) AddPetIDs(ids ...string) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[string]struct{}) - } - for i := range ids { - uc.pets[ids[i]] = struct{}{} - } + uc.mutation.AddPetIDs(ids...) return uc } @@ -117,10 +96,30 @@ func (uc *UserCreate) AddPets(p ...*Pet) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if len(uc.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -143,11 +142,11 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.id; value != nil { - u.ID = *value - _spec.ID.Value = *value + if id, ok := uc.mutation.ID(); ok { + u.ID = id + _spec.ID.Value = id } - if nodes := uc.groups; len(nodes) > 0 { + if nodes := uc.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -161,12 +160,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.parent; len(nodes) > 0 { + if nodes := uc.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -180,12 +179,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.children; len(nodes) > 0 { + if nodes := uc.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -199,12 +198,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.pets; len(nodes) > 0 { + if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -218,7 +217,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/customid/ent/user_delete.go b/entc/integration/customid/ent/user_delete.go index 738561d5d..4a1407c7d 100644 --- a/entc/integration/customid/ent/user_delete.go +++ b/entc/integration/customid/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/customid/ent/user_update.go b/entc/integration/customid/ent/user_update.go index 2f2bdfa90..403765f24 100644 --- a/entc/integration/customid/ent/user_update.go +++ b/entc/integration/customid/ent/user_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -22,15 +22,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - groups map[int]struct{} - parent map[int]struct{} - children map[int]struct{} - pets map[string]struct{} - removedGroups map[int]struct{} - clearedParent bool - removedChildren map[int]struct{} - removedPets map[string]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -41,12 +35,7 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // AddGroupIDs adds the groups edge to Group by ids. func (uu *UserUpdate) AddGroupIDs(ids ...int) *UserUpdate { - if uu.groups == nil { - uu.groups = make(map[int]struct{}) - } - for i := range ids { - uu.groups[ids[i]] = struct{}{} - } + uu.mutation.AddGroupIDs(ids...) return uu } @@ -61,10 +50,7 @@ func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { // SetParentID sets the parent edge to User by id. func (uu *UserUpdate) SetParentID(id int) *UserUpdate { - if uu.parent == nil { - uu.parent = make(map[int]struct{}) - } - uu.parent[id] = struct{}{} + uu.mutation.SetParentID(id) return uu } @@ -83,12 +69,7 @@ func (uu *UserUpdate) SetParent(u *User) *UserUpdate { // AddChildIDs adds the children edge to User by ids. func (uu *UserUpdate) AddChildIDs(ids ...int) *UserUpdate { - if uu.children == nil { - uu.children = make(map[int]struct{}) - } - for i := range ids { - uu.children[ids[i]] = struct{}{} - } + uu.mutation.AddChildIDs(ids...) return uu } @@ -103,12 +84,7 @@ func (uu *UserUpdate) AddChildren(u ...*User) *UserUpdate { // AddPetIDs adds the pets edge to Pet by ids. func (uu *UserUpdate) AddPetIDs(ids ...string) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[string]struct{}) - } - for i := range ids { - uu.pets[ids[i]] = struct{}{} - } + uu.mutation.AddPetIDs(ids...) return uu } @@ -123,12 +99,7 @@ func (uu *UserUpdate) AddPets(p ...*Pet) *UserUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (uu *UserUpdate) RemoveGroupIDs(ids ...int) *UserUpdate { - if uu.removedGroups == nil { - uu.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uu.removedGroups[ids[i]] = struct{}{} - } + uu.mutation.RemoveGroupIDs(ids...) return uu } @@ -143,18 +114,13 @@ func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { // ClearParent clears the parent edge to User. func (uu *UserUpdate) ClearParent() *UserUpdate { - uu.clearedParent = true + uu.mutation.ClearParent() return uu } // RemoveChildIDs removes the children edge to User by ids. func (uu *UserUpdate) RemoveChildIDs(ids ...int) *UserUpdate { - if uu.removedChildren == nil { - uu.removedChildren = make(map[int]struct{}) - } - for i := range ids { - uu.removedChildren[ids[i]] = struct{}{} - } + uu.mutation.RemoveChildIDs(ids...) return uu } @@ -169,12 +135,7 @@ func (uu *UserUpdate) RemoveChildren(u ...*User) *UserUpdate { // RemovePetIDs removes the pets edge to Pet by ids. func (uu *UserUpdate) RemovePetIDs(ids ...string) *UserUpdate { - if uu.removedPets == nil { - uu.removedPets = make(map[string]struct{}) - } - for i := range ids { - uu.removedPets[ids[i]] = struct{}{} - } + uu.mutation.RemovePetIDs(ids...) return uu } @@ -189,10 +150,31 @@ func (uu *UserUpdate) RemovePets(p ...*Pet) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if len(uu.parent) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"parent\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -235,7 +217,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if nodes := uu.removedGroups; len(nodes) > 0 { + if nodes := uu.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -249,12 +231,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.groups; len(nodes) > 0 { + if nodes := uu.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -268,12 +250,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedParent { + if uu.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -289,7 +271,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.parent; len(nodes) > 0 { + if nodes := uu.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -303,12 +285,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedChildren; len(nodes) > 0 { + if nodes := uu.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -322,12 +304,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.children; len(nodes) > 0 { + if nodes := uu.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -341,12 +323,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedPets; len(nodes) > 0 { + if nodes := uu.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -360,12 +342,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.pets; len(nodes) > 0 { + if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -379,7 +361,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -398,25 +380,13 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - groups map[int]struct{} - parent map[int]struct{} - children map[int]struct{} - pets map[string]struct{} - removedGroups map[int]struct{} - clearedParent bool - removedChildren map[int]struct{} - removedPets map[string]struct{} + hooks []Hook + mutation *UserMutation } // AddGroupIDs adds the groups edge to Group by ids. func (uuo *UserUpdateOne) AddGroupIDs(ids ...int) *UserUpdateOne { - if uuo.groups == nil { - uuo.groups = make(map[int]struct{}) - } - for i := range ids { - uuo.groups[ids[i]] = struct{}{} - } + uuo.mutation.AddGroupIDs(ids...) return uuo } @@ -431,10 +401,7 @@ func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { // SetParentID sets the parent edge to User by id. func (uuo *UserUpdateOne) SetParentID(id int) *UserUpdateOne { - if uuo.parent == nil { - uuo.parent = make(map[int]struct{}) - } - uuo.parent[id] = struct{}{} + uuo.mutation.SetParentID(id) return uuo } @@ -453,12 +420,7 @@ func (uuo *UserUpdateOne) SetParent(u *User) *UserUpdateOne { // AddChildIDs adds the children edge to User by ids. func (uuo *UserUpdateOne) AddChildIDs(ids ...int) *UserUpdateOne { - if uuo.children == nil { - uuo.children = make(map[int]struct{}) - } - for i := range ids { - uuo.children[ids[i]] = struct{}{} - } + uuo.mutation.AddChildIDs(ids...) return uuo } @@ -473,12 +435,7 @@ func (uuo *UserUpdateOne) AddChildren(u ...*User) *UserUpdateOne { // AddPetIDs adds the pets edge to Pet by ids. func (uuo *UserUpdateOne) AddPetIDs(ids ...string) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[string]struct{}) - } - for i := range ids { - uuo.pets[ids[i]] = struct{}{} - } + uuo.mutation.AddPetIDs(ids...) return uuo } @@ -493,12 +450,7 @@ func (uuo *UserUpdateOne) AddPets(p ...*Pet) *UserUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...int) *UserUpdateOne { - if uuo.removedGroups == nil { - uuo.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uuo.removedGroups[ids[i]] = struct{}{} - } + uuo.mutation.RemoveGroupIDs(ids...) return uuo } @@ -513,18 +465,13 @@ func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { // ClearParent clears the parent edge to User. func (uuo *UserUpdateOne) ClearParent() *UserUpdateOne { - uuo.clearedParent = true + uuo.mutation.ClearParent() return uuo } // RemoveChildIDs removes the children edge to User by ids. func (uuo *UserUpdateOne) RemoveChildIDs(ids ...int) *UserUpdateOne { - if uuo.removedChildren == nil { - uuo.removedChildren = make(map[int]struct{}) - } - for i := range ids { - uuo.removedChildren[ids[i]] = struct{}{} - } + uuo.mutation.RemoveChildIDs(ids...) return uuo } @@ -539,12 +486,7 @@ func (uuo *UserUpdateOne) RemoveChildren(u ...*User) *UserUpdateOne { // RemovePetIDs removes the pets edge to Pet by ids. func (uuo *UserUpdateOne) RemovePetIDs(ids ...string) *UserUpdateOne { - if uuo.removedPets == nil { - uuo.removedPets = make(map[string]struct{}) - } - for i := range ids { - uuo.removedPets[ids[i]] = struct{}{} - } + uuo.mutation.RemovePetIDs(ids...) return uuo } @@ -559,10 +501,31 @@ func (uuo *UserUpdateOne) RemovePets(p ...*Pet) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if len(uuo.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -593,13 +556,17 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if nodes := uuo.removedGroups; len(nodes) > 0 { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if nodes := uuo.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -613,12 +580,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.groups; len(nodes) > 0 { + if nodes := uuo.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -632,12 +599,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedParent { + if uuo.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -653,7 +620,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.parent; len(nodes) > 0 { + if nodes := uuo.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -667,12 +634,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedChildren; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -686,12 +653,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.children; len(nodes) > 0 { + if nodes := uuo.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -705,12 +672,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedPets; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -724,12 +691,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.pets; len(nodes) > 0 { + if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -743,7 +710,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/ent/card/card.go b/entc/integration/ent/card/card.go index 8b23c5858..e9f7df58b 100644 --- a/entc/integration/ent/card/card.go +++ b/entc/integration/ent/card/card.go @@ -8,24 +8,22 @@ package card import ( "time" - - "github.com/facebookincubator/ent" - "github.com/facebookincubator/ent/entc/integration/ent/schema" ) const ( // Label holds the string label denoting the card type in the database. Label = "card" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldCreateTime holds the string denoting the create_time vertex property in the database. - FieldCreateTime = "create_time" - // FieldUpdateTime holds the string denoting the update_time vertex property in the database. - FieldUpdateTime = "update_time" - // FieldNumber holds the string denoting the number vertex property in the database. - FieldNumber = "number" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" + FieldID = "id" // FieldCreateTime holds the string denoting the create_time vertex property in the database. + FieldCreateTime = "create_time" // FieldUpdateTime holds the string denoting the update_time vertex property in the database. + FieldUpdateTime = "update_time" // FieldNumber holds the string denoting the number vertex property in the database. + FieldNumber = "number" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" + + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // EdgeSpec holds the string denoting the spec edge name in mutations. + EdgeSpec = "spec" // Table holds the table name of the card in the database. Table = "cards" @@ -64,31 +62,14 @@ var ( ) var ( - mixin = schema.Card{}.Mixin() - mixinFields = [...][]ent.Field{ - mixin[0].Fields(), - } - fields = schema.Card{}.Fields() - - // descCreateTime is the schema descriptor for create_time field. - descCreateTime = mixinFields[0][0].Descriptor() // DefaultCreateTime holds the default value on creation for the create_time field. - DefaultCreateTime = descCreateTime.Default.(func() time.Time) - - // descUpdateTime is the schema descriptor for update_time field. - descUpdateTime = mixinFields[0][1].Descriptor() + DefaultCreateTime func() time.Time // DefaultUpdateTime holds the default value on creation for the update_time field. - DefaultUpdateTime = descUpdateTime.Default.(func() time.Time) + DefaultUpdateTime func() time.Time // UpdateDefaultUpdateTime holds the default value on update for the update_time field. - UpdateDefaultUpdateTime = descUpdateTime.UpdateDefault.(func() time.Time) - - // descNumber is the schema descriptor for number field. - descNumber = fields[0].Descriptor() + UpdateDefaultUpdateTime func() time.Time // NumberValidator is a validator for the "number" field. It is called by the builders before save. - NumberValidator = descNumber.Validators[0].(func(string) error) - - // descName is the schema descriptor for name field. - descName = fields[1].Descriptor() + NumberValidator func(string) error // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator = descName.Validators[0].(func(string) error) + NameValidator func(string) error ) diff --git a/entc/integration/ent/card_create.go b/entc/integration/ent/card_create.go index 41d5bd2bc..b6247d66f 100644 --- a/entc/integration/ent/card_create.go +++ b/entc/integration/ent/card_create.go @@ -23,17 +23,13 @@ import ( // CardCreate is the builder for creating a Card entity. type CardCreate struct { config - create_time *time.Time - update_time *time.Time - number *string - name *string - owner map[string]struct{} - spec map[string]struct{} + mutation *CardMutation + hooks []Hook } // SetCreateTime sets the create_time field. func (cc *CardCreate) SetCreateTime(t time.Time) *CardCreate { - cc.create_time = &t + cc.mutation.SetCreateTime(t) return cc } @@ -47,7 +43,7 @@ func (cc *CardCreate) SetNillableCreateTime(t *time.Time) *CardCreate { // SetUpdateTime sets the update_time field. func (cc *CardCreate) SetUpdateTime(t time.Time) *CardCreate { - cc.update_time = &t + cc.mutation.SetUpdateTime(t) return cc } @@ -61,13 +57,13 @@ func (cc *CardCreate) SetNillableUpdateTime(t *time.Time) *CardCreate { // SetNumber sets the number field. func (cc *CardCreate) SetNumber(s string) *CardCreate { - cc.number = &s + cc.mutation.SetNumber(s) return cc } // SetName sets the name field. func (cc *CardCreate) SetName(s string) *CardCreate { - cc.name = &s + cc.mutation.SetName(s) return cc } @@ -81,10 +77,7 @@ func (cc *CardCreate) SetNillableName(s *string) *CardCreate { // SetOwnerID sets the owner edge to User by id. func (cc *CardCreate) SetOwnerID(id string) *CardCreate { - if cc.owner == nil { - cc.owner = make(map[string]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -103,12 +96,7 @@ func (cc *CardCreate) SetOwner(u *User) *CardCreate { // AddSpecIDs adds the spec edge to Spec by ids. func (cc *CardCreate) AddSpecIDs(ids ...string) *CardCreate { - if cc.spec == nil { - cc.spec = make(map[string]struct{}) - } - for i := range ids { - cc.spec[ids[i]] = struct{}{} - } + cc.mutation.AddSpecIDs(ids...) return cc } @@ -123,29 +111,51 @@ func (cc *CardCreate) AddSpec(s ...*Spec) *CardCreate { // Save creates the Card in the database. func (cc *CardCreate) Save(ctx context.Context) (*Card, error) { - if cc.create_time == nil { + if _, ok := cc.mutation.CreateTime(); !ok { v := card.DefaultCreateTime() - cc.create_time = &v + cc.mutation.SetCreateTime(v) } - if cc.update_time == nil { + if _, ok := cc.mutation.UpdateTime(); !ok { v := card.DefaultUpdateTime() - cc.update_time = &v + cc.mutation.SetUpdateTime(v) } - if cc.number == nil { + if _, ok := cc.mutation.Number(); !ok { return nil, errors.New("ent: missing required field \"number\"") } - if err := card.NumberValidator(*cc.number); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"number\": %v", err) + if v, ok := cc.mutation.Number(); ok { + if err := card.NumberValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"number\": %v", err) + } } - if cc.name != nil { - if err := card.NameValidator(*cc.name); err != nil { + if v, ok := cc.mutation.Name(); ok { + if err := card.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(cc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Card + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } } - return cc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -168,39 +178,39 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { }, } ) - if value := cc.create_time; value != nil { + if value, ok := cc.mutation.CreateTime(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldCreateTime, }) - c.CreateTime = *value + c.CreateTime = value } - if value := cc.update_time; value != nil { + if value, ok := cc.mutation.UpdateTime(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldUpdateTime, }) - c.UpdateTime = *value + c.UpdateTime = value } - if value := cc.number; value != nil { + if value, ok := cc.mutation.Number(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldNumber, }) - c.Number = *value + c.Number = value } - if value := cc.name; value != nil { + if value, ok := cc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldName, }) - c.Name = *value + c.Name = value } - if nodes := cc.owner; len(nodes) > 0 { + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -214,7 +224,7 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -223,7 +233,7 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := cc.spec; len(nodes) > 0 { + if nodes := cc.mutation.SpecIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -237,7 +247,7 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/card_delete.go b/entc/integration/ent/card_delete.go index 33347e582..d6bf58811 100644 --- a/entc/integration/ent/card_delete.go +++ b/entc/integration/ent/card_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CardDelete is the builder for deleting a Card entity. type CardDelete struct { config + hooks []Hook + mutation *CardMutation predicates []predicate.Card } @@ -30,7 +33,30 @@ func (cd *CardDelete) Where(ps ...predicate.Card) *CardDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CardDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/card_update.go b/entc/integration/ent/card_update.go index 2b421e0e1..aade6dedf 100644 --- a/entc/integration/ent/card_update.go +++ b/entc/integration/ent/card_update.go @@ -8,10 +8,8 @@ package ent import ( "context" - "errors" "fmt" "strconv" - "time" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -25,16 +23,9 @@ import ( // CardUpdate is the builder for updating Card entities. type CardUpdate struct { config - - update_time *time.Time - - name *string - clearname bool - owner map[string]struct{} - spec map[string]struct{} - clearedOwner bool - removedSpec map[string]struct{} - predicates []predicate.Card + hooks []Hook + mutation *CardMutation + predicates []predicate.Card } // Where adds a new predicate for the builder. @@ -45,7 +36,7 @@ func (cu *CardUpdate) Where(ps ...predicate.Card) *CardUpdate { // SetName sets the name field. func (cu *CardUpdate) SetName(s string) *CardUpdate { - cu.name = &s + cu.mutation.SetName(s) return cu } @@ -59,17 +50,13 @@ func (cu *CardUpdate) SetNillableName(s *string) *CardUpdate { // ClearName clears the value of name. func (cu *CardUpdate) ClearName() *CardUpdate { - cu.name = nil - cu.clearname = true + cu.mutation.ClearName() return cu } // SetOwnerID sets the owner edge to User by id. func (cu *CardUpdate) SetOwnerID(id string) *CardUpdate { - if cu.owner == nil { - cu.owner = make(map[string]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -88,12 +75,7 @@ func (cu *CardUpdate) SetOwner(u *User) *CardUpdate { // AddSpecIDs adds the spec edge to Spec by ids. func (cu *CardUpdate) AddSpecIDs(ids ...string) *CardUpdate { - if cu.spec == nil { - cu.spec = make(map[string]struct{}) - } - for i := range ids { - cu.spec[ids[i]] = struct{}{} - } + cu.mutation.AddSpecIDs(ids...) return cu } @@ -108,18 +90,13 @@ func (cu *CardUpdate) AddSpec(s ...*Spec) *CardUpdate { // ClearOwner clears the owner edge to User. func (cu *CardUpdate) ClearOwner() *CardUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // RemoveSpecIDs removes the spec edge to Spec by ids. func (cu *CardUpdate) RemoveSpecIDs(ids ...string) *CardUpdate { - if cu.removedSpec == nil { - cu.removedSpec = make(map[string]struct{}) - } - for i := range ids { - cu.removedSpec[ids[i]] = struct{}{} - } + cu.mutation.RemoveSpecIDs(ids...) return cu } @@ -134,19 +111,40 @@ func (cu *CardUpdate) RemoveSpec(s ...*Spec) *CardUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CardUpdate) Save(ctx context.Context) (int, error) { - if cu.update_time == nil { + if _, ok := cu.mutation.UpdateTime(); !ok { v := card.UpdateDefaultUpdateTime() - cu.update_time = &v + cu.mutation.SetUpdateTime(v) } - if cu.name != nil { - if err := card.NameValidator(*cu.name); err != nil { + if v, ok := cu.mutation.Name(); ok { + if err := card.NameValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(cu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } } - return cu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -189,27 +187,27 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := cu.update_time; value != nil { + if value, ok := cu.mutation.UpdateTime(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldUpdateTime, }) } - if value := cu.name; value != nil { + if value, ok := cu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldName, }) } - if cu.clearname { + if cu.mutation.NameCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: card.FieldName, }) } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -225,7 +223,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.owner; len(nodes) > 0 { + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -239,7 +237,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -248,7 +246,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := cu.removedSpec; len(nodes) > 0 { + if nodes := cu.mutation.RemovedSpecIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -262,7 +260,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -271,7 +269,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.spec; len(nodes) > 0 { + if nodes := cu.mutation.SpecIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -285,7 +283,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -308,21 +306,13 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { // CardUpdateOne is the builder for updating a single Card entity. type CardUpdateOne struct { config - id string - - update_time *time.Time - - name *string - clearname bool - owner map[string]struct{} - spec map[string]struct{} - clearedOwner bool - removedSpec map[string]struct{} + hooks []Hook + mutation *CardMutation } // SetName sets the name field. func (cuo *CardUpdateOne) SetName(s string) *CardUpdateOne { - cuo.name = &s + cuo.mutation.SetName(s) return cuo } @@ -336,17 +326,13 @@ func (cuo *CardUpdateOne) SetNillableName(s *string) *CardUpdateOne { // ClearName clears the value of name. func (cuo *CardUpdateOne) ClearName() *CardUpdateOne { - cuo.name = nil - cuo.clearname = true + cuo.mutation.ClearName() return cuo } // SetOwnerID sets the owner edge to User by id. func (cuo *CardUpdateOne) SetOwnerID(id string) *CardUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[string]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -365,12 +351,7 @@ func (cuo *CardUpdateOne) SetOwner(u *User) *CardUpdateOne { // AddSpecIDs adds the spec edge to Spec by ids. func (cuo *CardUpdateOne) AddSpecIDs(ids ...string) *CardUpdateOne { - if cuo.spec == nil { - cuo.spec = make(map[string]struct{}) - } - for i := range ids { - cuo.spec[ids[i]] = struct{}{} - } + cuo.mutation.AddSpecIDs(ids...) return cuo } @@ -385,18 +366,13 @@ func (cuo *CardUpdateOne) AddSpec(s ...*Spec) *CardUpdateOne { // ClearOwner clears the owner edge to User. func (cuo *CardUpdateOne) ClearOwner() *CardUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // RemoveSpecIDs removes the spec edge to Spec by ids. func (cuo *CardUpdateOne) RemoveSpecIDs(ids ...string) *CardUpdateOne { - if cuo.removedSpec == nil { - cuo.removedSpec = make(map[string]struct{}) - } - for i := range ids { - cuo.removedSpec[ids[i]] = struct{}{} - } + cuo.mutation.RemoveSpecIDs(ids...) return cuo } @@ -411,19 +387,40 @@ func (cuo *CardUpdateOne) RemoveSpec(s ...*Spec) *CardUpdateOne { // Save executes the query and returns the updated entity. func (cuo *CardUpdateOne) Save(ctx context.Context) (*Card, error) { - if cuo.update_time == nil { + if _, ok := cuo.mutation.UpdateTime(); !ok { v := card.UpdateDefaultUpdateTime() - cuo.update_time = &v + cuo.mutation.SetUpdateTime(v) } - if cuo.name != nil { - if err := card.NameValidator(*cuo.name); err != nil { + if v, ok := cuo.mutation.Name(); ok { + if err := card.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(cuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Card + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } } - return cuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -454,33 +451,37 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { Table: card.Table, Columns: card.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeString, Column: card.FieldID, }, }, } - if value := cuo.update_time; value != nil { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Card.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.UpdateTime(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldUpdateTime, }) } - if value := cuo.name; value != nil { + if value, ok := cuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldName, }) } - if cuo.clearname { + if cuo.mutation.NameCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: card.FieldName, }) } - if cuo.clearedOwner { + if cuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -496,7 +497,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.owner; len(nodes) > 0 { + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -510,7 +511,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -519,7 +520,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := cuo.removedSpec; len(nodes) > 0 { + if nodes := cuo.mutation.RemovedSpecIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -533,7 +534,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -542,7 +543,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.spec; len(nodes) > 0 { + if nodes := cuo.mutation.SpecIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -556,7 +557,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/client.go b/entc/integration/ent/client.go index 3f9a02a49..1f365fa1f 100644 --- a/entc/integration/ent/client.go +++ b/entc/integration/ent/client.go @@ -64,24 +64,27 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Card: NewCardClient(c), - Comment: NewCommentClient(c), - FieldType: NewFieldTypeClient(c), - File: NewFileClient(c), - FileType: NewFileTypeClient(c), - Group: NewGroupClient(c), - GroupInfo: NewGroupInfoClient(c), - Item: NewItemClient(c), - Node: NewNodeClient(c), - Pet: NewPetClient(c), - Spec: NewSpecClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Card = NewCardClient(c.config) + c.Comment = NewCommentClient(c.config) + c.FieldType = NewFieldTypeClient(c.config) + c.File = NewFileClient(c.config) + c.FileType = NewFileTypeClient(c.config) + c.Group = NewGroupClient(c.config) + c.GroupInfo = NewGroupInfoClient(c.config) + c.Item = NewItemClient(c.config) + c.Node = NewNodeClient(c.config) + c.Pet = NewPetClient(c.config) + c.Spec = NewSpecClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -109,7 +112,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Card: NewCardClient(cfg), @@ -138,23 +141,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Card: NewCardClient(cfg), - Comment: NewCommentClient(cfg), - FieldType: NewFieldTypeClient(cfg), - File: NewFileClient(cfg), - FileType: NewFileTypeClient(cfg), - Group: NewGroupClient(cfg), - GroupInfo: NewGroupInfoClient(cfg), - Item: NewItemClient(cfg), - Node: NewNodeClient(cfg), - Pet: NewPetClient(cfg), - Spec: NewSpecClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -162,6 +152,23 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Card.Use(hooks...) + c.Comment.Use(hooks...) + c.FieldType.Use(hooks...) + c.File.Use(hooks...) + c.FileType.Use(hooks...) + c.Group.Use(hooks...) + c.GroupInfo.Use(hooks...) + c.Item.Use(hooks...) + c.Node.Use(hooks...) + c.Pet.Use(hooks...) + c.Spec.Use(hooks...) + c.User.Use(hooks...) +} + // CardClient is a client for the Card schema. type CardClient struct { config @@ -172,14 +179,22 @@ func NewCardClient(c config) *CardClient { return &CardClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `card.Hooks(f(g(h())))`. +func (c *CardClient) Use(hooks ...Hook) { + c.hooks.Card = append(c.hooks.Card, hooks...) +} + // Create returns a create builder for Card. func (c *CardClient) Create() *CardCreate { - return &CardCreate{config: c.config} + mutation := newCardMutation(c.config, OpCreate) + return &CardCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Card. func (c *CardClient) Update() *CardUpdate { - return &CardUpdate{config: c.config} + mutation := newCardMutation(c.config, OpUpdate) + return &CardUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -189,12 +204,15 @@ func (c *CardClient) UpdateOne(ca *Card) *CardUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CardClient) UpdateOneID(id string) *CardUpdateOne { - return &CardUpdateOne{config: c.config, id: id} + mutation := newCardMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CardUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Card. func (c *CardClient) Delete() *CardDelete { - return &CardDelete{config: c.config} + mutation := newCardMutation(c.config, OpDelete) + return &CardDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -204,7 +222,10 @@ func (c *CardClient) DeleteOne(ca *Card) *CardDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CardClient) DeleteOneID(id string) *CardDeleteOne { - return &CardDeleteOne{c.Delete().Where(card.ID(id))} + builder := c.Delete().Where(card.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CardDeleteOne{builder} } // Create returns a query builder for Card. @@ -254,6 +275,11 @@ func (c *CardClient) QuerySpec(ca *Card) *SpecQuery { return query } +// Hooks returns the client hooks. +func (c *CardClient) Hooks() []Hook { + return c.hooks.Card +} + // CommentClient is a client for the Comment schema. type CommentClient struct { config @@ -264,14 +290,22 @@ func NewCommentClient(c config) *CommentClient { return &CommentClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `comment.Hooks(f(g(h())))`. +func (c *CommentClient) Use(hooks ...Hook) { + c.hooks.Comment = append(c.hooks.Comment, hooks...) +} + // Create returns a create builder for Comment. func (c *CommentClient) Create() *CommentCreate { - return &CommentCreate{config: c.config} + mutation := newCommentMutation(c.config, OpCreate) + return &CommentCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Comment. func (c *CommentClient) Update() *CommentUpdate { - return &CommentUpdate{config: c.config} + mutation := newCommentMutation(c.config, OpUpdate) + return &CommentUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -281,12 +315,15 @@ func (c *CommentClient) UpdateOne(co *Comment) *CommentUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CommentClient) UpdateOneID(id string) *CommentUpdateOne { - return &CommentUpdateOne{config: c.config, id: id} + mutation := newCommentMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CommentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Comment. func (c *CommentClient) Delete() *CommentDelete { - return &CommentDelete{config: c.config} + mutation := newCommentMutation(c.config, OpDelete) + return &CommentDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -296,7 +333,10 @@ func (c *CommentClient) DeleteOne(co *Comment) *CommentDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CommentClient) DeleteOneID(id string) *CommentDeleteOne { - return &CommentDeleteOne{c.Delete().Where(comment.ID(id))} + builder := c.Delete().Where(comment.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CommentDeleteOne{builder} } // Create returns a query builder for Comment. @@ -318,6 +358,11 @@ func (c *CommentClient) GetX(ctx context.Context, id string) *Comment { return co } +// Hooks returns the client hooks. +func (c *CommentClient) Hooks() []Hook { + return c.hooks.Comment +} + // FieldTypeClient is a client for the FieldType schema. type FieldTypeClient struct { config @@ -328,14 +373,22 @@ func NewFieldTypeClient(c config) *FieldTypeClient { return &FieldTypeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `fieldtype.Hooks(f(g(h())))`. +func (c *FieldTypeClient) Use(hooks ...Hook) { + c.hooks.FieldType = append(c.hooks.FieldType, hooks...) +} + // Create returns a create builder for FieldType. func (c *FieldTypeClient) Create() *FieldTypeCreate { - return &FieldTypeCreate{config: c.config} + mutation := newFieldTypeMutation(c.config, OpCreate) + return &FieldTypeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for FieldType. func (c *FieldTypeClient) Update() *FieldTypeUpdate { - return &FieldTypeUpdate{config: c.config} + mutation := newFieldTypeMutation(c.config, OpUpdate) + return &FieldTypeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -345,12 +398,15 @@ func (c *FieldTypeClient) UpdateOne(ft *FieldType) *FieldTypeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *FieldTypeClient) UpdateOneID(id string) *FieldTypeUpdateOne { - return &FieldTypeUpdateOne{config: c.config, id: id} + mutation := newFieldTypeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &FieldTypeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for FieldType. func (c *FieldTypeClient) Delete() *FieldTypeDelete { - return &FieldTypeDelete{config: c.config} + mutation := newFieldTypeMutation(c.config, OpDelete) + return &FieldTypeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -360,7 +416,10 @@ func (c *FieldTypeClient) DeleteOne(ft *FieldType) *FieldTypeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *FieldTypeClient) DeleteOneID(id string) *FieldTypeDeleteOne { - return &FieldTypeDeleteOne{c.Delete().Where(fieldtype.ID(id))} + builder := c.Delete().Where(fieldtype.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &FieldTypeDeleteOne{builder} } // Create returns a query builder for FieldType. @@ -382,6 +441,11 @@ func (c *FieldTypeClient) GetX(ctx context.Context, id string) *FieldType { return ft } +// Hooks returns the client hooks. +func (c *FieldTypeClient) Hooks() []Hook { + return c.hooks.FieldType +} + // FileClient is a client for the File schema. type FileClient struct { config @@ -392,14 +456,22 @@ func NewFileClient(c config) *FileClient { return &FileClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `file.Hooks(f(g(h())))`. +func (c *FileClient) Use(hooks ...Hook) { + c.hooks.File = append(c.hooks.File, hooks...) +} + // Create returns a create builder for File. func (c *FileClient) Create() *FileCreate { - return &FileCreate{config: c.config} + mutation := newFileMutation(c.config, OpCreate) + return &FileCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for File. func (c *FileClient) Update() *FileUpdate { - return &FileUpdate{config: c.config} + mutation := newFileMutation(c.config, OpUpdate) + return &FileUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -409,12 +481,15 @@ func (c *FileClient) UpdateOne(f *File) *FileUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *FileClient) UpdateOneID(id string) *FileUpdateOne { - return &FileUpdateOne{config: c.config, id: id} + mutation := newFileMutation(c.config, OpUpdateOne) + mutation.id = &id + return &FileUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for File. func (c *FileClient) Delete() *FileDelete { - return &FileDelete{config: c.config} + mutation := newFileMutation(c.config, OpDelete) + return &FileDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -424,7 +499,10 @@ func (c *FileClient) DeleteOne(f *File) *FileDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *FileClient) DeleteOneID(id string) *FileDeleteOne { - return &FileDeleteOne{c.Delete().Where(file.ID(id))} + builder := c.Delete().Where(file.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &FileDeleteOne{builder} } // Create returns a query builder for File. @@ -474,6 +552,11 @@ func (c *FileClient) QueryType(f *File) *FileTypeQuery { return query } +// Hooks returns the client hooks. +func (c *FileClient) Hooks() []Hook { + return c.hooks.File +} + // FileTypeClient is a client for the FileType schema. type FileTypeClient struct { config @@ -484,14 +567,22 @@ func NewFileTypeClient(c config) *FileTypeClient { return &FileTypeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `filetype.Hooks(f(g(h())))`. +func (c *FileTypeClient) Use(hooks ...Hook) { + c.hooks.FileType = append(c.hooks.FileType, hooks...) +} + // Create returns a create builder for FileType. func (c *FileTypeClient) Create() *FileTypeCreate { - return &FileTypeCreate{config: c.config} + mutation := newFileTypeMutation(c.config, OpCreate) + return &FileTypeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for FileType. func (c *FileTypeClient) Update() *FileTypeUpdate { - return &FileTypeUpdate{config: c.config} + mutation := newFileTypeMutation(c.config, OpUpdate) + return &FileTypeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -501,12 +592,15 @@ func (c *FileTypeClient) UpdateOne(ft *FileType) *FileTypeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *FileTypeClient) UpdateOneID(id string) *FileTypeUpdateOne { - return &FileTypeUpdateOne{config: c.config, id: id} + mutation := newFileTypeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &FileTypeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for FileType. func (c *FileTypeClient) Delete() *FileTypeDelete { - return &FileTypeDelete{config: c.config} + mutation := newFileTypeMutation(c.config, OpDelete) + return &FileTypeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -516,7 +610,10 @@ func (c *FileTypeClient) DeleteOne(ft *FileType) *FileTypeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *FileTypeClient) DeleteOneID(id string) *FileTypeDeleteOne { - return &FileTypeDeleteOne{c.Delete().Where(filetype.ID(id))} + builder := c.Delete().Where(filetype.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &FileTypeDeleteOne{builder} } // Create returns a query builder for FileType. @@ -552,6 +649,11 @@ func (c *FileTypeClient) QueryFiles(ft *FileType) *FileQuery { return query } +// Hooks returns the client hooks. +func (c *FileTypeClient) Hooks() []Hook { + return c.hooks.FileType +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -562,14 +664,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -579,12 +689,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id string) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -594,7 +707,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id string) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -672,6 +788,11 @@ func (c *GroupClient) QueryInfo(gr *Group) *GroupInfoQuery { return query } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // GroupInfoClient is a client for the GroupInfo schema. type GroupInfoClient struct { config @@ -682,14 +803,22 @@ func NewGroupInfoClient(c config) *GroupInfoClient { return &GroupInfoClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `groupinfo.Hooks(f(g(h())))`. +func (c *GroupInfoClient) Use(hooks ...Hook) { + c.hooks.GroupInfo = append(c.hooks.GroupInfo, hooks...) +} + // Create returns a create builder for GroupInfo. func (c *GroupInfoClient) Create() *GroupInfoCreate { - return &GroupInfoCreate{config: c.config} + mutation := newGroupInfoMutation(c.config, OpCreate) + return &GroupInfoCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for GroupInfo. func (c *GroupInfoClient) Update() *GroupInfoUpdate { - return &GroupInfoUpdate{config: c.config} + mutation := newGroupInfoMutation(c.config, OpUpdate) + return &GroupInfoUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -699,12 +828,15 @@ func (c *GroupInfoClient) UpdateOne(gi *GroupInfo) *GroupInfoUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupInfoClient) UpdateOneID(id string) *GroupInfoUpdateOne { - return &GroupInfoUpdateOne{config: c.config, id: id} + mutation := newGroupInfoMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupInfoUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for GroupInfo. func (c *GroupInfoClient) Delete() *GroupInfoDelete { - return &GroupInfoDelete{config: c.config} + mutation := newGroupInfoMutation(c.config, OpDelete) + return &GroupInfoDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -714,7 +846,10 @@ func (c *GroupInfoClient) DeleteOne(gi *GroupInfo) *GroupInfoDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupInfoClient) DeleteOneID(id string) *GroupInfoDeleteOne { - return &GroupInfoDeleteOne{c.Delete().Where(groupinfo.ID(id))} + builder := c.Delete().Where(groupinfo.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupInfoDeleteOne{builder} } // Create returns a query builder for GroupInfo. @@ -750,6 +885,11 @@ func (c *GroupInfoClient) QueryGroups(gi *GroupInfo) *GroupQuery { return query } +// Hooks returns the client hooks. +func (c *GroupInfoClient) Hooks() []Hook { + return c.hooks.GroupInfo +} + // ItemClient is a client for the Item schema. type ItemClient struct { config @@ -760,14 +900,22 @@ func NewItemClient(c config) *ItemClient { return &ItemClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `item.Hooks(f(g(h())))`. +func (c *ItemClient) Use(hooks ...Hook) { + c.hooks.Item = append(c.hooks.Item, hooks...) +} + // Create returns a create builder for Item. func (c *ItemClient) Create() *ItemCreate { - return &ItemCreate{config: c.config} + mutation := newItemMutation(c.config, OpCreate) + return &ItemCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Item. func (c *ItemClient) Update() *ItemUpdate { - return &ItemUpdate{config: c.config} + mutation := newItemMutation(c.config, OpUpdate) + return &ItemUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -777,12 +925,15 @@ func (c *ItemClient) UpdateOne(i *Item) *ItemUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *ItemClient) UpdateOneID(id string) *ItemUpdateOne { - return &ItemUpdateOne{config: c.config, id: id} + mutation := newItemMutation(c.config, OpUpdateOne) + mutation.id = &id + return &ItemUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Item. func (c *ItemClient) Delete() *ItemDelete { - return &ItemDelete{config: c.config} + mutation := newItemMutation(c.config, OpDelete) + return &ItemDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -792,7 +943,10 @@ func (c *ItemClient) DeleteOne(i *Item) *ItemDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *ItemClient) DeleteOneID(id string) *ItemDeleteOne { - return &ItemDeleteOne{c.Delete().Where(item.ID(id))} + builder := c.Delete().Where(item.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &ItemDeleteOne{builder} } // Create returns a query builder for Item. @@ -814,6 +968,11 @@ func (c *ItemClient) GetX(ctx context.Context, id string) *Item { return i } +// Hooks returns the client hooks. +func (c *ItemClient) Hooks() []Hook { + return c.hooks.Item +} + // NodeClient is a client for the Node schema. type NodeClient struct { config @@ -824,14 +983,22 @@ func NewNodeClient(c config) *NodeClient { return &NodeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `node.Hooks(f(g(h())))`. +func (c *NodeClient) Use(hooks ...Hook) { + c.hooks.Node = append(c.hooks.Node, hooks...) +} + // Create returns a create builder for Node. func (c *NodeClient) Create() *NodeCreate { - return &NodeCreate{config: c.config} + mutation := newNodeMutation(c.config, OpCreate) + return &NodeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Node. func (c *NodeClient) Update() *NodeUpdate { - return &NodeUpdate{config: c.config} + mutation := newNodeMutation(c.config, OpUpdate) + return &NodeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -841,12 +1008,15 @@ func (c *NodeClient) UpdateOne(n *Node) *NodeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *NodeClient) UpdateOneID(id string) *NodeUpdateOne { - return &NodeUpdateOne{config: c.config, id: id} + mutation := newNodeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &NodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Node. func (c *NodeClient) Delete() *NodeDelete { - return &NodeDelete{config: c.config} + mutation := newNodeMutation(c.config, OpDelete) + return &NodeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -856,7 +1026,10 @@ func (c *NodeClient) DeleteOne(n *Node) *NodeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *NodeClient) DeleteOneID(id string) *NodeDeleteOne { - return &NodeDeleteOne{c.Delete().Where(node.ID(id))} + builder := c.Delete().Where(node.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &NodeDeleteOne{builder} } // Create returns a query builder for Node. @@ -906,6 +1079,11 @@ func (c *NodeClient) QueryNext(n *Node) *NodeQuery { return query } +// Hooks returns the client hooks. +func (c *NodeClient) Hooks() []Hook { + return c.hooks.Node +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -916,14 +1094,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -933,12 +1119,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id string) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -948,7 +1137,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id string) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -998,6 +1190,11 @@ func (c *PetClient) QueryOwner(pe *Pet) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // SpecClient is a client for the Spec schema. type SpecClient struct { config @@ -1008,14 +1205,22 @@ func NewSpecClient(c config) *SpecClient { return &SpecClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `spec.Hooks(f(g(h())))`. +func (c *SpecClient) Use(hooks ...Hook) { + c.hooks.Spec = append(c.hooks.Spec, hooks...) +} + // Create returns a create builder for Spec. func (c *SpecClient) Create() *SpecCreate { - return &SpecCreate{config: c.config} + mutation := newSpecMutation(c.config, OpCreate) + return &SpecCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Spec. func (c *SpecClient) Update() *SpecUpdate { - return &SpecUpdate{config: c.config} + mutation := newSpecMutation(c.config, OpUpdate) + return &SpecUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -1025,12 +1230,15 @@ func (c *SpecClient) UpdateOne(s *Spec) *SpecUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *SpecClient) UpdateOneID(id string) *SpecUpdateOne { - return &SpecUpdateOne{config: c.config, id: id} + mutation := newSpecMutation(c.config, OpUpdateOne) + mutation.id = &id + return &SpecUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Spec. func (c *SpecClient) Delete() *SpecDelete { - return &SpecDelete{config: c.config} + mutation := newSpecMutation(c.config, OpDelete) + return &SpecDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -1040,7 +1248,10 @@ func (c *SpecClient) DeleteOne(s *Spec) *SpecDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *SpecClient) DeleteOneID(id string) *SpecDeleteOne { - return &SpecDeleteOne{c.Delete().Where(spec.ID(id))} + builder := c.Delete().Where(spec.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &SpecDeleteOne{builder} } // Create returns a query builder for Spec. @@ -1076,6 +1287,11 @@ func (c *SpecClient) QueryCard(s *Spec) *CardQuery { return query } +// Hooks returns the client hooks. +func (c *SpecClient) Hooks() []Hook { + return c.hooks.Spec +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -1086,14 +1302,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -1103,12 +1327,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id string) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -1118,7 +1345,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id string) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -1293,3 +1523,8 @@ func (c *UserClient) QueryParent(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/ent/comment/comment.go b/entc/integration/ent/comment/comment.go index 55f6694ba..66b972b48 100644 --- a/entc/integration/ent/comment/comment.go +++ b/entc/integration/ent/comment/comment.go @@ -10,12 +10,9 @@ const ( // Label holds the string label denoting the comment type in the database. Label = "comment" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldUniqueInt holds the string denoting the unique_int vertex property in the database. - FieldUniqueInt = "unique_int" - // FieldUniqueFloat holds the string denoting the unique_float vertex property in the database. - FieldUniqueFloat = "unique_float" - // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. + FieldID = "id" // FieldUniqueInt holds the string denoting the unique_int vertex property in the database. + FieldUniqueInt = "unique_int" // FieldUniqueFloat holds the string denoting the unique_float vertex property in the database. + FieldUniqueFloat = "unique_float" // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. FieldNillableInt = "nillable_int" // Table holds the table name of the comment in the database. diff --git a/entc/integration/ent/comment_create.go b/entc/integration/ent/comment_create.go index 1ecb1f3f5..092cc9643 100644 --- a/entc/integration/ent/comment_create.go +++ b/entc/integration/ent/comment_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,26 +20,25 @@ import ( // CommentCreate is the builder for creating a Comment entity. type CommentCreate struct { config - unique_int *int - unique_float *float64 - nillable_int *int + mutation *CommentMutation + hooks []Hook } // SetUniqueInt sets the unique_int field. func (cc *CommentCreate) SetUniqueInt(i int) *CommentCreate { - cc.unique_int = &i + cc.mutation.SetUniqueInt(i) return cc } // SetUniqueFloat sets the unique_float field. func (cc *CommentCreate) SetUniqueFloat(f float64) *CommentCreate { - cc.unique_float = &f + cc.mutation.SetUniqueFloat(f) return cc } // SetNillableInt sets the nillable_int field. func (cc *CommentCreate) SetNillableInt(i int) *CommentCreate { - cc.nillable_int = &i + cc.mutation.SetNillableInt(i) return cc } @@ -52,13 +52,36 @@ func (cc *CommentCreate) SetNillableNillableInt(i *int) *CommentCreate { // Save creates the Comment in the database. func (cc *CommentCreate) Save(ctx context.Context) (*Comment, error) { - if cc.unique_int == nil { + if _, ok := cc.mutation.UniqueInt(); !ok { return nil, errors.New("ent: missing required field \"unique_int\"") } - if cc.unique_float == nil { + if _, ok := cc.mutation.UniqueFloat(); !ok { return nil, errors.New("ent: missing required field \"unique_float\"") } - return cc.sqlSave(ctx) + var ( + err error + node *Comment + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -81,29 +104,29 @@ func (cc *CommentCreate) sqlSave(ctx context.Context) (*Comment, error) { }, } ) - if value := cc.unique_int; value != nil { + if value, ok := cc.mutation.UniqueInt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldUniqueInt, }) - c.UniqueInt = *value + c.UniqueInt = value } - if value := cc.unique_float; value != nil { + if value, ok := cc.mutation.UniqueFloat(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: comment.FieldUniqueFloat, }) - c.UniqueFloat = *value + c.UniqueFloat = value } - if value := cc.nillable_int; value != nil { + if value, ok := cc.mutation.NillableInt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldNillableInt, }) - c.NillableInt = value + c.NillableInt = &value } if err := sqlgraph.CreateNode(ctx, cc.driver, _spec); err != nil { if cerr, ok := isSQLConstraintError(err); ok { diff --git a/entc/integration/ent/comment_delete.go b/entc/integration/ent/comment_delete.go index ccb2829f4..d08910771 100644 --- a/entc/integration/ent/comment_delete.go +++ b/entc/integration/ent/comment_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CommentDelete is the builder for deleting a Comment entity. type CommentDelete struct { config + hooks []Hook + mutation *CommentMutation predicates []predicate.Comment } @@ -30,7 +33,30 @@ func (cd *CommentDelete) Where(ps ...predicate.Comment) *CommentDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CommentDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/comment_update.go b/entc/integration/ent/comment_update.go index e01dec070..13ba450db 100644 --- a/entc/integration/ent/comment_update.go +++ b/entc/integration/ent/comment_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,14 +20,9 @@ import ( // CommentUpdate is the builder for updating Comment entities. type CommentUpdate struct { config - unique_int *int - addunique_int *int - unique_float *float64 - addunique_float *float64 - nillable_int *int - addnillable_int *int - clearnillable_int bool - predicates []predicate.Comment + hooks []Hook + mutation *CommentMutation + predicates []predicate.Comment } // Where adds a new predicate for the builder. @@ -37,42 +33,34 @@ func (cu *CommentUpdate) Where(ps ...predicate.Comment) *CommentUpdate { // SetUniqueInt sets the unique_int field. func (cu *CommentUpdate) SetUniqueInt(i int) *CommentUpdate { - cu.unique_int = &i - cu.addunique_int = nil + cu.mutation.ResetUniqueInt() + cu.mutation.SetUniqueInt(i) return cu } // AddUniqueInt adds i to unique_int. func (cu *CommentUpdate) AddUniqueInt(i int) *CommentUpdate { - if cu.addunique_int == nil { - cu.addunique_int = &i - } else { - *cu.addunique_int += i - } + cu.mutation.AddUniqueInt(i) return cu } // SetUniqueFloat sets the unique_float field. func (cu *CommentUpdate) SetUniqueFloat(f float64) *CommentUpdate { - cu.unique_float = &f - cu.addunique_float = nil + cu.mutation.ResetUniqueFloat() + cu.mutation.SetUniqueFloat(f) return cu } // AddUniqueFloat adds f to unique_float. func (cu *CommentUpdate) AddUniqueFloat(f float64) *CommentUpdate { - if cu.addunique_float == nil { - cu.addunique_float = &f - } else { - *cu.addunique_float += f - } + cu.mutation.AddUniqueFloat(f) return cu } // SetNillableInt sets the nillable_int field. func (cu *CommentUpdate) SetNillableInt(i int) *CommentUpdate { - cu.nillable_int = &i - cu.addnillable_int = nil + cu.mutation.ResetNillableInt() + cu.mutation.SetNillableInt(i) return cu } @@ -86,24 +74,42 @@ func (cu *CommentUpdate) SetNillableNillableInt(i *int) *CommentUpdate { // AddNillableInt adds i to nillable_int. func (cu *CommentUpdate) AddNillableInt(i int) *CommentUpdate { - if cu.addnillable_int == nil { - cu.addnillable_int = &i - } else { - *cu.addnillable_int += i - } + cu.mutation.AddNillableInt(i) return cu } // ClearNillableInt clears the value of nillable_int. func (cu *CommentUpdate) ClearNillableInt() *CommentUpdate { - cu.nillable_int = nil - cu.clearnillable_int = true + cu.mutation.ClearNillableInt() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CommentUpdate) Save(ctx context.Context) (int, error) { - return cu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -146,49 +152,49 @@ func (cu *CommentUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := cu.unique_int; value != nil { + if value, ok := cu.mutation.UniqueInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldUniqueInt, }) } - if value := cu.addunique_int; value != nil { + if value, ok := cu.mutation.AddedUniqueInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldUniqueInt, }) } - if value := cu.unique_float; value != nil { + if value, ok := cu.mutation.UniqueFloat(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: comment.FieldUniqueFloat, }) } - if value := cu.addunique_float; value != nil { + if value, ok := cu.mutation.AddedUniqueFloat(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: comment.FieldUniqueFloat, }) } - if value := cu.nillable_int; value != nil { + if value, ok := cu.mutation.NillableInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldNillableInt, }) } - if value := cu.addnillable_int; value != nil { + if value, ok := cu.mutation.AddedNillableInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldNillableInt, }) } - if cu.clearnillable_int { + if cu.mutation.NillableIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: comment.FieldNillableInt, @@ -208,54 +214,40 @@ func (cu *CommentUpdate) sqlSave(ctx context.Context) (n int, err error) { // CommentUpdateOne is the builder for updating a single Comment entity. type CommentUpdateOne struct { config - id string - unique_int *int - addunique_int *int - unique_float *float64 - addunique_float *float64 - nillable_int *int - addnillable_int *int - clearnillable_int bool + hooks []Hook + mutation *CommentMutation } // SetUniqueInt sets the unique_int field. func (cuo *CommentUpdateOne) SetUniqueInt(i int) *CommentUpdateOne { - cuo.unique_int = &i - cuo.addunique_int = nil + cuo.mutation.ResetUniqueInt() + cuo.mutation.SetUniqueInt(i) return cuo } // AddUniqueInt adds i to unique_int. func (cuo *CommentUpdateOne) AddUniqueInt(i int) *CommentUpdateOne { - if cuo.addunique_int == nil { - cuo.addunique_int = &i - } else { - *cuo.addunique_int += i - } + cuo.mutation.AddUniqueInt(i) return cuo } // SetUniqueFloat sets the unique_float field. func (cuo *CommentUpdateOne) SetUniqueFloat(f float64) *CommentUpdateOne { - cuo.unique_float = &f - cuo.addunique_float = nil + cuo.mutation.ResetUniqueFloat() + cuo.mutation.SetUniqueFloat(f) return cuo } // AddUniqueFloat adds f to unique_float. func (cuo *CommentUpdateOne) AddUniqueFloat(f float64) *CommentUpdateOne { - if cuo.addunique_float == nil { - cuo.addunique_float = &f - } else { - *cuo.addunique_float += f - } + cuo.mutation.AddUniqueFloat(f) return cuo } // SetNillableInt sets the nillable_int field. func (cuo *CommentUpdateOne) SetNillableInt(i int) *CommentUpdateOne { - cuo.nillable_int = &i - cuo.addnillable_int = nil + cuo.mutation.ResetNillableInt() + cuo.mutation.SetNillableInt(i) return cuo } @@ -269,24 +261,42 @@ func (cuo *CommentUpdateOne) SetNillableNillableInt(i *int) *CommentUpdateOne { // AddNillableInt adds i to nillable_int. func (cuo *CommentUpdateOne) AddNillableInt(i int) *CommentUpdateOne { - if cuo.addnillable_int == nil { - cuo.addnillable_int = &i - } else { - *cuo.addnillable_int += i - } + cuo.mutation.AddNillableInt(i) return cuo } // ClearNillableInt clears the value of nillable_int. func (cuo *CommentUpdateOne) ClearNillableInt() *CommentUpdateOne { - cuo.nillable_int = nil - cuo.clearnillable_int = true + cuo.mutation.ClearNillableInt() return cuo } // Save executes the query and returns the updated entity. func (cuo *CommentUpdateOne) Save(ctx context.Context) (*Comment, error) { - return cuo.sqlSave(ctx) + var ( + err error + node *Comment + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -317,55 +327,59 @@ func (cuo *CommentUpdateOne) sqlSave(ctx context.Context) (c *Comment, err error Table: comment.Table, Columns: comment.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeString, Column: comment.FieldID, }, }, } - if value := cuo.unique_int; value != nil { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Comment.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.UniqueInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldUniqueInt, }) } - if value := cuo.addunique_int; value != nil { + if value, ok := cuo.mutation.AddedUniqueInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldUniqueInt, }) } - if value := cuo.unique_float; value != nil { + if value, ok := cuo.mutation.UniqueFloat(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: comment.FieldUniqueFloat, }) } - if value := cuo.addunique_float; value != nil { + if value, ok := cuo.mutation.AddedUniqueFloat(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: comment.FieldUniqueFloat, }) } - if value := cuo.nillable_int; value != nil { + if value, ok := cuo.mutation.NillableInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldNillableInt, }) } - if value := cuo.addnillable_int; value != nil { + if value, ok := cuo.mutation.AddedNillableInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: comment.FieldNillableInt, }) } - if cuo.clearnillable_int { + if cuo.mutation.NillableIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: comment.FieldNillableInt, diff --git a/entc/integration/ent/config.go b/entc/integration/ent/config.go index dd64c4cf6..d034d7be0 100644 --- a/entc/integration/ent/config.go +++ b/entc/integration/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,24 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Card []ent.Hook + Comment []ent.Hook + FieldType []ent.Hook + File []ent.Hook + FileType []ent.Hook + Group []ent.Hook + GroupInfo []ent.Hook + Item []ent.Hook + Node []ent.Hook + Pet []ent.Hook + Spec []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/ent/ent.go b/entc/integration/ent/ent.go index 5d811eb5a..bdb5c3926 100644 --- a/entc/integration/ent/ent.go +++ b/entc/integration/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/ent/fieldtype/fieldtype.go b/entc/integration/ent/fieldtype/fieldtype.go index e7fc5b3e5..952ee09c3 100644 --- a/entc/integration/ent/fieldtype/fieldtype.go +++ b/entc/integration/ent/fieldtype/fieldtype.go @@ -8,63 +8,37 @@ package fieldtype import ( "fmt" - - "github.com/facebookincubator/ent/entc/integration/ent/schema" ) const ( // Label holds the string label denoting the fieldtype type in the database. Label = "field_type" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldInt holds the string denoting the int vertex property in the database. - FieldInt = "int" - // FieldInt8 holds the string denoting the int8 vertex property in the database. - FieldInt8 = "int8" - // FieldInt16 holds the string denoting the int16 vertex property in the database. - FieldInt16 = "int16" - // FieldInt32 holds the string denoting the int32 vertex property in the database. - FieldInt32 = "int32" - // FieldInt64 holds the string denoting the int64 vertex property in the database. - FieldInt64 = "int64" - // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. - FieldOptionalInt = "optional_int" - // FieldOptionalInt8 holds the string denoting the optional_int8 vertex property in the database. - FieldOptionalInt8 = "optional_int8" - // FieldOptionalInt16 holds the string denoting the optional_int16 vertex property in the database. - FieldOptionalInt16 = "optional_int16" - // FieldOptionalInt32 holds the string denoting the optional_int32 vertex property in the database. - FieldOptionalInt32 = "optional_int32" - // FieldOptionalInt64 holds the string denoting the optional_int64 vertex property in the database. - FieldOptionalInt64 = "optional_int64" - // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. - FieldNillableInt = "nillable_int" - // FieldNillableInt8 holds the string denoting the nillable_int8 vertex property in the database. - FieldNillableInt8 = "nillable_int8" - // FieldNillableInt16 holds the string denoting the nillable_int16 vertex property in the database. - FieldNillableInt16 = "nillable_int16" - // FieldNillableInt32 holds the string denoting the nillable_int32 vertex property in the database. - FieldNillableInt32 = "nillable_int32" - // FieldNillableInt64 holds the string denoting the nillable_int64 vertex property in the database. - FieldNillableInt64 = "nillable_int64" - // FieldValidateOptionalInt32 holds the string denoting the validate_optional_int32 vertex property in the database. - FieldValidateOptionalInt32 = "validate_optional_int32" - // FieldOptionalUint holds the string denoting the optional_uint vertex property in the database. - FieldOptionalUint = "optional_uint" - // FieldOptionalUint8 holds the string denoting the optional_uint8 vertex property in the database. - FieldOptionalUint8 = "optional_uint8" - // FieldOptionalUint16 holds the string denoting the optional_uint16 vertex property in the database. - FieldOptionalUint16 = "optional_uint16" - // FieldOptionalUint32 holds the string denoting the optional_uint32 vertex property in the database. - FieldOptionalUint32 = "optional_uint32" - // FieldOptionalUint64 holds the string denoting the optional_uint64 vertex property in the database. - FieldOptionalUint64 = "optional_uint64" - // FieldState holds the string denoting the state vertex property in the database. - FieldState = "state" - // FieldOptionalFloat holds the string denoting the optional_float vertex property in the database. - FieldOptionalFloat = "optional_float" - // FieldOptionalFloat32 holds the string denoting the optional_float32 vertex property in the database. - FieldOptionalFloat32 = "optional_float32" + FieldID = "id" // FieldInt holds the string denoting the int vertex property in the database. + FieldInt = "int" // FieldInt8 holds the string denoting the int8 vertex property in the database. + FieldInt8 = "int8" // FieldInt16 holds the string denoting the int16 vertex property in the database. + FieldInt16 = "int16" // FieldInt32 holds the string denoting the int32 vertex property in the database. + FieldInt32 = "int32" // FieldInt64 holds the string denoting the int64 vertex property in the database. + FieldInt64 = "int64" // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. + FieldOptionalInt = "optional_int" // FieldOptionalInt8 holds the string denoting the optional_int8 vertex property in the database. + FieldOptionalInt8 = "optional_int8" // FieldOptionalInt16 holds the string denoting the optional_int16 vertex property in the database. + FieldOptionalInt16 = "optional_int16" // FieldOptionalInt32 holds the string denoting the optional_int32 vertex property in the database. + FieldOptionalInt32 = "optional_int32" // FieldOptionalInt64 holds the string denoting the optional_int64 vertex property in the database. + FieldOptionalInt64 = "optional_int64" // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. + FieldNillableInt = "nillable_int" // FieldNillableInt8 holds the string denoting the nillable_int8 vertex property in the database. + FieldNillableInt8 = "nillable_int8" // FieldNillableInt16 holds the string denoting the nillable_int16 vertex property in the database. + FieldNillableInt16 = "nillable_int16" // FieldNillableInt32 holds the string denoting the nillable_int32 vertex property in the database. + FieldNillableInt32 = "nillable_int32" // FieldNillableInt64 holds the string denoting the nillable_int64 vertex property in the database. + FieldNillableInt64 = "nillable_int64" // FieldValidateOptionalInt32 holds the string denoting the validate_optional_int32 vertex property in the database. + FieldValidateOptionalInt32 = "validate_optional_int32" // FieldOptionalUint holds the string denoting the optional_uint vertex property in the database. + FieldOptionalUint = "optional_uint" // FieldOptionalUint8 holds the string denoting the optional_uint8 vertex property in the database. + FieldOptionalUint8 = "optional_uint8" // FieldOptionalUint16 holds the string denoting the optional_uint16 vertex property in the database. + FieldOptionalUint16 = "optional_uint16" // FieldOptionalUint32 holds the string denoting the optional_uint32 vertex property in the database. + FieldOptionalUint32 = "optional_uint32" // FieldOptionalUint64 holds the string denoting the optional_uint64 vertex property in the database. + FieldOptionalUint64 = "optional_uint64" // FieldState holds the string denoting the state vertex property in the database. + FieldState = "state" // FieldOptionalFloat holds the string denoting the optional_float vertex property in the database. + FieldOptionalFloat = "optional_float" // FieldOptionalFloat32 holds the string denoting the optional_float32 vertex property in the database. + FieldOptionalFloat32 = "optional_float32" // Table holds the table name of the fieldtype in the database. Table = "field_types" @@ -100,12 +74,8 @@ var Columns = []string{ } var ( - fields = schema.FieldType{}.Fields() - - // descValidateOptionalInt32 is the schema descriptor for validate_optional_int32 field. - descValidateOptionalInt32 = fields[15].Descriptor() // ValidateOptionalInt32Validator is a validator for the "validate_optional_int32" field. It is called by the builders before save. - ValidateOptionalInt32Validator = descValidateOptionalInt32.Validators[0].(func(int32) error) + ValidateOptionalInt32Validator func(int32) error ) // State defines the type for the state enum field. diff --git a/entc/integration/ent/fieldtype_create.go b/entc/integration/ent/fieldtype_create.go index 05ba13cb9..6cc79f83c 100644 --- a/entc/integration/ent/fieldtype_create.go +++ b/entc/integration/ent/fieldtype_create.go @@ -20,65 +20,43 @@ import ( // FieldTypeCreate is the builder for creating a FieldType entity. type FieldTypeCreate struct { config - int *int - int8 *int8 - int16 *int16 - int32 *int32 - int64 *int64 - optional_int *int - optional_int8 *int8 - optional_int16 *int16 - optional_int32 *int32 - optional_int64 *int64 - nillable_int *int - nillable_int8 *int8 - nillable_int16 *int16 - nillable_int32 *int32 - nillable_int64 *int64 - validate_optional_int32 *int32 - optional_uint *uint - optional_uint8 *uint8 - optional_uint16 *uint16 - optional_uint32 *uint32 - optional_uint64 *uint64 - state *fieldtype.State - optional_float *float64 - optional_float32 *float32 + mutation *FieldTypeMutation + hooks []Hook } // SetInt sets the int field. func (ftc *FieldTypeCreate) SetInt(i int) *FieldTypeCreate { - ftc.int = &i + ftc.mutation.SetInt(i) return ftc } // SetInt8 sets the int8 field. func (ftc *FieldTypeCreate) SetInt8(i int8) *FieldTypeCreate { - ftc.int8 = &i + ftc.mutation.SetInt8(i) return ftc } // SetInt16 sets the int16 field. func (ftc *FieldTypeCreate) SetInt16(i int16) *FieldTypeCreate { - ftc.int16 = &i + ftc.mutation.SetInt16(i) return ftc } // SetInt32 sets the int32 field. func (ftc *FieldTypeCreate) SetInt32(i int32) *FieldTypeCreate { - ftc.int32 = &i + ftc.mutation.SetInt32(i) return ftc } // SetInt64 sets the int64 field. func (ftc *FieldTypeCreate) SetInt64(i int64) *FieldTypeCreate { - ftc.int64 = &i + ftc.mutation.SetInt64(i) return ftc } // SetOptionalInt sets the optional_int field. func (ftc *FieldTypeCreate) SetOptionalInt(i int) *FieldTypeCreate { - ftc.optional_int = &i + ftc.mutation.SetOptionalInt(i) return ftc } @@ -92,7 +70,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt(i *int) *FieldTypeCreate { // SetOptionalInt8 sets the optional_int8 field. func (ftc *FieldTypeCreate) SetOptionalInt8(i int8) *FieldTypeCreate { - ftc.optional_int8 = &i + ftc.mutation.SetOptionalInt8(i) return ftc } @@ -106,7 +84,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt8(i *int8) *FieldTypeCreate { // SetOptionalInt16 sets the optional_int16 field. func (ftc *FieldTypeCreate) SetOptionalInt16(i int16) *FieldTypeCreate { - ftc.optional_int16 = &i + ftc.mutation.SetOptionalInt16(i) return ftc } @@ -120,7 +98,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt16(i *int16) *FieldTypeCreate // SetOptionalInt32 sets the optional_int32 field. func (ftc *FieldTypeCreate) SetOptionalInt32(i int32) *FieldTypeCreate { - ftc.optional_int32 = &i + ftc.mutation.SetOptionalInt32(i) return ftc } @@ -134,7 +112,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt32(i *int32) *FieldTypeCreate // SetOptionalInt64 sets the optional_int64 field. func (ftc *FieldTypeCreate) SetOptionalInt64(i int64) *FieldTypeCreate { - ftc.optional_int64 = &i + ftc.mutation.SetOptionalInt64(i) return ftc } @@ -148,7 +126,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt64(i *int64) *FieldTypeCreate // SetNillableInt sets the nillable_int field. func (ftc *FieldTypeCreate) SetNillableInt(i int) *FieldTypeCreate { - ftc.nillable_int = &i + ftc.mutation.SetNillableInt(i) return ftc } @@ -162,7 +140,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt(i *int) *FieldTypeCreate { // SetNillableInt8 sets the nillable_int8 field. func (ftc *FieldTypeCreate) SetNillableInt8(i int8) *FieldTypeCreate { - ftc.nillable_int8 = &i + ftc.mutation.SetNillableInt8(i) return ftc } @@ -176,7 +154,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt8(i *int8) *FieldTypeCreate { // SetNillableInt16 sets the nillable_int16 field. func (ftc *FieldTypeCreate) SetNillableInt16(i int16) *FieldTypeCreate { - ftc.nillable_int16 = &i + ftc.mutation.SetNillableInt16(i) return ftc } @@ -190,7 +168,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt16(i *int16) *FieldTypeCreate // SetNillableInt32 sets the nillable_int32 field. func (ftc *FieldTypeCreate) SetNillableInt32(i int32) *FieldTypeCreate { - ftc.nillable_int32 = &i + ftc.mutation.SetNillableInt32(i) return ftc } @@ -204,7 +182,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt32(i *int32) *FieldTypeCreate // SetNillableInt64 sets the nillable_int64 field. func (ftc *FieldTypeCreate) SetNillableInt64(i int64) *FieldTypeCreate { - ftc.nillable_int64 = &i + ftc.mutation.SetNillableInt64(i) return ftc } @@ -218,7 +196,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt64(i *int64) *FieldTypeCreate // SetValidateOptionalInt32 sets the validate_optional_int32 field. func (ftc *FieldTypeCreate) SetValidateOptionalInt32(i int32) *FieldTypeCreate { - ftc.validate_optional_int32 = &i + ftc.mutation.SetValidateOptionalInt32(i) return ftc } @@ -232,7 +210,7 @@ func (ftc *FieldTypeCreate) SetNillableValidateOptionalInt32(i *int32) *FieldTyp // SetOptionalUint sets the optional_uint field. func (ftc *FieldTypeCreate) SetOptionalUint(u uint) *FieldTypeCreate { - ftc.optional_uint = &u + ftc.mutation.SetOptionalUint(u) return ftc } @@ -246,7 +224,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint(u *uint) *FieldTypeCreate { // SetOptionalUint8 sets the optional_uint8 field. func (ftc *FieldTypeCreate) SetOptionalUint8(u uint8) *FieldTypeCreate { - ftc.optional_uint8 = &u + ftc.mutation.SetOptionalUint8(u) return ftc } @@ -260,7 +238,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint8(u *uint8) *FieldTypeCreate // SetOptionalUint16 sets the optional_uint16 field. func (ftc *FieldTypeCreate) SetOptionalUint16(u uint16) *FieldTypeCreate { - ftc.optional_uint16 = &u + ftc.mutation.SetOptionalUint16(u) return ftc } @@ -274,7 +252,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint16(u *uint16) *FieldTypeCreat // SetOptionalUint32 sets the optional_uint32 field. func (ftc *FieldTypeCreate) SetOptionalUint32(u uint32) *FieldTypeCreate { - ftc.optional_uint32 = &u + ftc.mutation.SetOptionalUint32(u) return ftc } @@ -288,7 +266,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint32(u *uint32) *FieldTypeCreat // SetOptionalUint64 sets the optional_uint64 field. func (ftc *FieldTypeCreate) SetOptionalUint64(u uint64) *FieldTypeCreate { - ftc.optional_uint64 = &u + ftc.mutation.SetOptionalUint64(u) return ftc } @@ -302,7 +280,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint64(u *uint64) *FieldTypeCreat // SetState sets the state field. func (ftc *FieldTypeCreate) SetState(f fieldtype.State) *FieldTypeCreate { - ftc.state = &f + ftc.mutation.SetState(f) return ftc } @@ -316,7 +294,7 @@ func (ftc *FieldTypeCreate) SetNillableState(f *fieldtype.State) *FieldTypeCreat // SetOptionalFloat sets the optional_float field. func (ftc *FieldTypeCreate) SetOptionalFloat(f float64) *FieldTypeCreate { - ftc.optional_float = &f + ftc.mutation.SetOptionalFloat(f) return ftc } @@ -330,7 +308,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalFloat(f *float64) *FieldTypeCreat // SetOptionalFloat32 sets the optional_float32 field. func (ftc *FieldTypeCreate) SetOptionalFloat32(f float32) *FieldTypeCreate { - ftc.optional_float32 = &f + ftc.mutation.SetOptionalFloat32(f) return ftc } @@ -344,32 +322,55 @@ func (ftc *FieldTypeCreate) SetNillableOptionalFloat32(f *float32) *FieldTypeCre // Save creates the FieldType in the database. func (ftc *FieldTypeCreate) Save(ctx context.Context) (*FieldType, error) { - if ftc.int == nil { + if _, ok := ftc.mutation.Int(); !ok { return nil, errors.New("ent: missing required field \"int\"") } - if ftc.int8 == nil { + if _, ok := ftc.mutation.Int8(); !ok { return nil, errors.New("ent: missing required field \"int8\"") } - if ftc.int16 == nil { + if _, ok := ftc.mutation.Int16(); !ok { return nil, errors.New("ent: missing required field \"int16\"") } - if ftc.int32 == nil { + if _, ok := ftc.mutation.Int32(); !ok { return nil, errors.New("ent: missing required field \"int32\"") } - if ftc.int64 == nil { + if _, ok := ftc.mutation.Int64(); !ok { return nil, errors.New("ent: missing required field \"int64\"") } - if ftc.validate_optional_int32 != nil { - if err := fieldtype.ValidateOptionalInt32Validator(*ftc.validate_optional_int32); err != nil { + if v, ok := ftc.mutation.ValidateOptionalInt32(); ok { + if err := fieldtype.ValidateOptionalInt32Validator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"validate_optional_int32\": %v", err) } } - if ftc.state != nil { - if err := fieldtype.StateValidator(*ftc.state); err != nil { + if v, ok := ftc.mutation.State(); ok { + if err := fieldtype.StateValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"state\": %v", err) } } - return ftc.sqlSave(ctx) + var ( + err error + node *FieldType + ) + if len(ftc.hooks) == 0 { + node, err = ftc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftc.mutation = mutation + node, err = ftc.sqlSave(ctx) + return node, err + }) + for i := len(ftc.hooks); i > 0; i-- { + mut = ftc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -392,197 +393,197 @@ func (ftc *FieldTypeCreate) sqlSave(ctx context.Context) (*FieldType, error) { }, } ) - if value := ftc.int; value != nil { + if value, ok := ftc.mutation.Int(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldInt, }) - ft.Int = *value + ft.Int = value } - if value := ftc.int8; value != nil { + if value, ok := ftc.mutation.Int8(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldInt8, }) - ft.Int8 = *value + ft.Int8 = value } - if value := ftc.int16; value != nil { + if value, ok := ftc.mutation.Int16(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldInt16, }) - ft.Int16 = *value + ft.Int16 = value } - if value := ftc.int32; value != nil { + if value, ok := ftc.mutation.Int32(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldInt32, }) - ft.Int32 = *value + ft.Int32 = value } - if value := ftc.int64; value != nil { + if value, ok := ftc.mutation.Int64(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldInt64, }) - ft.Int64 = *value + ft.Int64 = value } - if value := ftc.optional_int; value != nil { + if value, ok := ftc.mutation.OptionalInt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt, }) - ft.OptionalInt = *value + ft.OptionalInt = value } - if value := ftc.optional_int8; value != nil { + if value, ok := ftc.mutation.OptionalInt8(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt8, }) - ft.OptionalInt8 = *value + ft.OptionalInt8 = value } - if value := ftc.optional_int16; value != nil { + if value, ok := ftc.mutation.OptionalInt16(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt16, }) - ft.OptionalInt16 = *value + ft.OptionalInt16 = value } - if value := ftc.optional_int32; value != nil { + if value, ok := ftc.mutation.OptionalInt32(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt32, }) - ft.OptionalInt32 = *value + ft.OptionalInt32 = value } - if value := ftc.optional_int64; value != nil { + if value, ok := ftc.mutation.OptionalInt64(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt64, }) - ft.OptionalInt64 = *value + ft.OptionalInt64 = value } - if value := ftc.nillable_int; value != nil { + if value, ok := ftc.mutation.NillableInt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt, }) - ft.NillableInt = value + ft.NillableInt = &value } - if value := ftc.nillable_int8; value != nil { + if value, ok := ftc.mutation.NillableInt8(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt8, }) - ft.NillableInt8 = value + ft.NillableInt8 = &value } - if value := ftc.nillable_int16; value != nil { + if value, ok := ftc.mutation.NillableInt16(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt16, }) - ft.NillableInt16 = value + ft.NillableInt16 = &value } - if value := ftc.nillable_int32; value != nil { + if value, ok := ftc.mutation.NillableInt32(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt32, }) - ft.NillableInt32 = value + ft.NillableInt32 = &value } - if value := ftc.nillable_int64; value != nil { + if value, ok := ftc.mutation.NillableInt64(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt64, }) - ft.NillableInt64 = value + ft.NillableInt64 = &value } - if value := ftc.validate_optional_int32; value != nil { + if value, ok := ftc.mutation.ValidateOptionalInt32(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldValidateOptionalInt32, }) - ft.ValidateOptionalInt32 = *value + ft.ValidateOptionalInt32 = value } - if value := ftc.optional_uint; value != nil { + if value, ok := ftc.mutation.OptionalUint(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeUint, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint, }) - ft.OptionalUint = *value + ft.OptionalUint = value } - if value := ftc.optional_uint8; value != nil { + if value, ok := ftc.mutation.OptionalUint8(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeUint8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint8, }) - ft.OptionalUint8 = *value + ft.OptionalUint8 = value } - if value := ftc.optional_uint16; value != nil { + if value, ok := ftc.mutation.OptionalUint16(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeUint16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint16, }) - ft.OptionalUint16 = *value + ft.OptionalUint16 = value } - if value := ftc.optional_uint32; value != nil { + if value, ok := ftc.mutation.OptionalUint32(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeUint32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint32, }) - ft.OptionalUint32 = *value + ft.OptionalUint32 = value } - if value := ftc.optional_uint64; value != nil { + if value, ok := ftc.mutation.OptionalUint64(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeUint64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint64, }) - ft.OptionalUint64 = *value + ft.OptionalUint64 = value } - if value := ftc.state; value != nil { + if value, ok := ftc.mutation.State(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: fieldtype.FieldState, }) - ft.State = *value + ft.State = value } - if value := ftc.optional_float; value != nil { + if value, ok := ftc.mutation.OptionalFloat(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat, }) - ft.OptionalFloat = *value + ft.OptionalFloat = value } - if value := ftc.optional_float32; value != nil { + if value, ok := ftc.mutation.OptionalFloat32(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat32, }) - ft.OptionalFloat32 = *value + ft.OptionalFloat32 = value } if err := sqlgraph.CreateNode(ctx, ftc.driver, _spec); err != nil { if cerr, ok := isSQLConstraintError(err); ok { diff --git a/entc/integration/ent/fieldtype_delete.go b/entc/integration/ent/fieldtype_delete.go index bed9a8024..aa4eedb77 100644 --- a/entc/integration/ent/fieldtype_delete.go +++ b/entc/integration/ent/fieldtype_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // FieldTypeDelete is the builder for deleting a FieldType entity. type FieldTypeDelete struct { config + hooks []Hook + mutation *FieldTypeMutation predicates []predicate.FieldType } @@ -30,7 +33,30 @@ func (ftd *FieldTypeDelete) Where(ps ...predicate.FieldType) *FieldTypeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ftd *FieldTypeDelete) Exec(ctx context.Context) (int, error) { - return ftd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ftd.hooks) == 0 { + affected, err = ftd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftd.mutation = mutation + affected, err = ftd.sqlExec(ctx) + return affected, err + }) + for i := len(ftd.hooks); i > 0; i-- { + mut = ftd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/fieldtype_update.go b/entc/integration/ent/fieldtype_update.go index 049230354..68fad8245 100644 --- a/entc/integration/ent/fieldtype_update.go +++ b/entc/integration/ent/fieldtype_update.go @@ -20,73 +20,9 @@ import ( // FieldTypeUpdate is the builder for updating FieldType entities. type FieldTypeUpdate struct { config - int *int - addint *int - int8 *int8 - addint8 *int8 - int16 *int16 - addint16 *int16 - int32 *int32 - addint32 *int32 - int64 *int64 - addint64 *int64 - optional_int *int - addoptional_int *int - clearoptional_int bool - optional_int8 *int8 - addoptional_int8 *int8 - clearoptional_int8 bool - optional_int16 *int16 - addoptional_int16 *int16 - clearoptional_int16 bool - optional_int32 *int32 - addoptional_int32 *int32 - clearoptional_int32 bool - optional_int64 *int64 - addoptional_int64 *int64 - clearoptional_int64 bool - nillable_int *int - addnillable_int *int - clearnillable_int bool - nillable_int8 *int8 - addnillable_int8 *int8 - clearnillable_int8 bool - nillable_int16 *int16 - addnillable_int16 *int16 - clearnillable_int16 bool - nillable_int32 *int32 - addnillable_int32 *int32 - clearnillable_int32 bool - nillable_int64 *int64 - addnillable_int64 *int64 - clearnillable_int64 bool - validate_optional_int32 *int32 - addvalidate_optional_int32 *int32 - clearvalidate_optional_int32 bool - optional_uint *uint - addoptional_uint *uint - clearoptional_uint bool - optional_uint8 *uint8 - addoptional_uint8 *uint8 - clearoptional_uint8 bool - optional_uint16 *uint16 - addoptional_uint16 *uint16 - clearoptional_uint16 bool - optional_uint32 *uint32 - addoptional_uint32 *uint32 - clearoptional_uint32 bool - optional_uint64 *uint64 - addoptional_uint64 *uint64 - clearoptional_uint64 bool - state *fieldtype.State - clearstate bool - optional_float *float64 - addoptional_float *float64 - clearoptional_float bool - optional_float32 *float32 - addoptional_float32 *float32 - clearoptional_float32 bool - predicates []predicate.FieldType + hooks []Hook + mutation *FieldTypeMutation + predicates []predicate.FieldType } // Where adds a new predicate for the builder. @@ -97,93 +33,73 @@ func (ftu *FieldTypeUpdate) Where(ps ...predicate.FieldType) *FieldTypeUpdate { // SetInt sets the int field. func (ftu *FieldTypeUpdate) SetInt(i int) *FieldTypeUpdate { - ftu.int = &i - ftu.addint = nil + ftu.mutation.ResetInt() + ftu.mutation.SetInt(i) return ftu } // AddInt adds i to int. func (ftu *FieldTypeUpdate) AddInt(i int) *FieldTypeUpdate { - if ftu.addint == nil { - ftu.addint = &i - } else { - *ftu.addint += i - } + ftu.mutation.AddInt(i) return ftu } // SetInt8 sets the int8 field. func (ftu *FieldTypeUpdate) SetInt8(i int8) *FieldTypeUpdate { - ftu.int8 = &i - ftu.addint8 = nil + ftu.mutation.ResetInt8() + ftu.mutation.SetInt8(i) return ftu } // AddInt8 adds i to int8. func (ftu *FieldTypeUpdate) AddInt8(i int8) *FieldTypeUpdate { - if ftu.addint8 == nil { - ftu.addint8 = &i - } else { - *ftu.addint8 += i - } + ftu.mutation.AddInt8(i) return ftu } // SetInt16 sets the int16 field. func (ftu *FieldTypeUpdate) SetInt16(i int16) *FieldTypeUpdate { - ftu.int16 = &i - ftu.addint16 = nil + ftu.mutation.ResetInt16() + ftu.mutation.SetInt16(i) return ftu } // AddInt16 adds i to int16. func (ftu *FieldTypeUpdate) AddInt16(i int16) *FieldTypeUpdate { - if ftu.addint16 == nil { - ftu.addint16 = &i - } else { - *ftu.addint16 += i - } + ftu.mutation.AddInt16(i) return ftu } // SetInt32 sets the int32 field. func (ftu *FieldTypeUpdate) SetInt32(i int32) *FieldTypeUpdate { - ftu.int32 = &i - ftu.addint32 = nil + ftu.mutation.ResetInt32() + ftu.mutation.SetInt32(i) return ftu } // AddInt32 adds i to int32. func (ftu *FieldTypeUpdate) AddInt32(i int32) *FieldTypeUpdate { - if ftu.addint32 == nil { - ftu.addint32 = &i - } else { - *ftu.addint32 += i - } + ftu.mutation.AddInt32(i) return ftu } // SetInt64 sets the int64 field. func (ftu *FieldTypeUpdate) SetInt64(i int64) *FieldTypeUpdate { - ftu.int64 = &i - ftu.addint64 = nil + ftu.mutation.ResetInt64() + ftu.mutation.SetInt64(i) return ftu } // AddInt64 adds i to int64. func (ftu *FieldTypeUpdate) AddInt64(i int64) *FieldTypeUpdate { - if ftu.addint64 == nil { - ftu.addint64 = &i - } else { - *ftu.addint64 += i - } + ftu.mutation.AddInt64(i) return ftu } // SetOptionalInt sets the optional_int field. func (ftu *FieldTypeUpdate) SetOptionalInt(i int) *FieldTypeUpdate { - ftu.optional_int = &i - ftu.addoptional_int = nil + ftu.mutation.ResetOptionalInt() + ftu.mutation.SetOptionalInt(i) return ftu } @@ -197,25 +113,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt(i *int) *FieldTypeUpdate { // AddOptionalInt adds i to optional_int. func (ftu *FieldTypeUpdate) AddOptionalInt(i int) *FieldTypeUpdate { - if ftu.addoptional_int == nil { - ftu.addoptional_int = &i - } else { - *ftu.addoptional_int += i - } + ftu.mutation.AddOptionalInt(i) return ftu } // ClearOptionalInt clears the value of optional_int. func (ftu *FieldTypeUpdate) ClearOptionalInt() *FieldTypeUpdate { - ftu.optional_int = nil - ftu.clearoptional_int = true + ftu.mutation.ClearOptionalInt() return ftu } // SetOptionalInt8 sets the optional_int8 field. func (ftu *FieldTypeUpdate) SetOptionalInt8(i int8) *FieldTypeUpdate { - ftu.optional_int8 = &i - ftu.addoptional_int8 = nil + ftu.mutation.ResetOptionalInt8() + ftu.mutation.SetOptionalInt8(i) return ftu } @@ -229,25 +140,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt8(i *int8) *FieldTypeUpdate { // AddOptionalInt8 adds i to optional_int8. func (ftu *FieldTypeUpdate) AddOptionalInt8(i int8) *FieldTypeUpdate { - if ftu.addoptional_int8 == nil { - ftu.addoptional_int8 = &i - } else { - *ftu.addoptional_int8 += i - } + ftu.mutation.AddOptionalInt8(i) return ftu } // ClearOptionalInt8 clears the value of optional_int8. func (ftu *FieldTypeUpdate) ClearOptionalInt8() *FieldTypeUpdate { - ftu.optional_int8 = nil - ftu.clearoptional_int8 = true + ftu.mutation.ClearOptionalInt8() return ftu } // SetOptionalInt16 sets the optional_int16 field. func (ftu *FieldTypeUpdate) SetOptionalInt16(i int16) *FieldTypeUpdate { - ftu.optional_int16 = &i - ftu.addoptional_int16 = nil + ftu.mutation.ResetOptionalInt16() + ftu.mutation.SetOptionalInt16(i) return ftu } @@ -261,25 +167,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt16(i *int16) *FieldTypeUpdate // AddOptionalInt16 adds i to optional_int16. func (ftu *FieldTypeUpdate) AddOptionalInt16(i int16) *FieldTypeUpdate { - if ftu.addoptional_int16 == nil { - ftu.addoptional_int16 = &i - } else { - *ftu.addoptional_int16 += i - } + ftu.mutation.AddOptionalInt16(i) return ftu } // ClearOptionalInt16 clears the value of optional_int16. func (ftu *FieldTypeUpdate) ClearOptionalInt16() *FieldTypeUpdate { - ftu.optional_int16 = nil - ftu.clearoptional_int16 = true + ftu.mutation.ClearOptionalInt16() return ftu } // SetOptionalInt32 sets the optional_int32 field. func (ftu *FieldTypeUpdate) SetOptionalInt32(i int32) *FieldTypeUpdate { - ftu.optional_int32 = &i - ftu.addoptional_int32 = nil + ftu.mutation.ResetOptionalInt32() + ftu.mutation.SetOptionalInt32(i) return ftu } @@ -293,25 +194,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt32(i *int32) *FieldTypeUpdate // AddOptionalInt32 adds i to optional_int32. func (ftu *FieldTypeUpdate) AddOptionalInt32(i int32) *FieldTypeUpdate { - if ftu.addoptional_int32 == nil { - ftu.addoptional_int32 = &i - } else { - *ftu.addoptional_int32 += i - } + ftu.mutation.AddOptionalInt32(i) return ftu } // ClearOptionalInt32 clears the value of optional_int32. func (ftu *FieldTypeUpdate) ClearOptionalInt32() *FieldTypeUpdate { - ftu.optional_int32 = nil - ftu.clearoptional_int32 = true + ftu.mutation.ClearOptionalInt32() return ftu } // SetOptionalInt64 sets the optional_int64 field. func (ftu *FieldTypeUpdate) SetOptionalInt64(i int64) *FieldTypeUpdate { - ftu.optional_int64 = &i - ftu.addoptional_int64 = nil + ftu.mutation.ResetOptionalInt64() + ftu.mutation.SetOptionalInt64(i) return ftu } @@ -325,25 +221,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt64(i *int64) *FieldTypeUpdate // AddOptionalInt64 adds i to optional_int64. func (ftu *FieldTypeUpdate) AddOptionalInt64(i int64) *FieldTypeUpdate { - if ftu.addoptional_int64 == nil { - ftu.addoptional_int64 = &i - } else { - *ftu.addoptional_int64 += i - } + ftu.mutation.AddOptionalInt64(i) return ftu } // ClearOptionalInt64 clears the value of optional_int64. func (ftu *FieldTypeUpdate) ClearOptionalInt64() *FieldTypeUpdate { - ftu.optional_int64 = nil - ftu.clearoptional_int64 = true + ftu.mutation.ClearOptionalInt64() return ftu } // SetNillableInt sets the nillable_int field. func (ftu *FieldTypeUpdate) SetNillableInt(i int) *FieldTypeUpdate { - ftu.nillable_int = &i - ftu.addnillable_int = nil + ftu.mutation.ResetNillableInt() + ftu.mutation.SetNillableInt(i) return ftu } @@ -357,25 +248,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt(i *int) *FieldTypeUpdate { // AddNillableInt adds i to nillable_int. func (ftu *FieldTypeUpdate) AddNillableInt(i int) *FieldTypeUpdate { - if ftu.addnillable_int == nil { - ftu.addnillable_int = &i - } else { - *ftu.addnillable_int += i - } + ftu.mutation.AddNillableInt(i) return ftu } // ClearNillableInt clears the value of nillable_int. func (ftu *FieldTypeUpdate) ClearNillableInt() *FieldTypeUpdate { - ftu.nillable_int = nil - ftu.clearnillable_int = true + ftu.mutation.ClearNillableInt() return ftu } // SetNillableInt8 sets the nillable_int8 field. func (ftu *FieldTypeUpdate) SetNillableInt8(i int8) *FieldTypeUpdate { - ftu.nillable_int8 = &i - ftu.addnillable_int8 = nil + ftu.mutation.ResetNillableInt8() + ftu.mutation.SetNillableInt8(i) return ftu } @@ -389,25 +275,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt8(i *int8) *FieldTypeUpdate { // AddNillableInt8 adds i to nillable_int8. func (ftu *FieldTypeUpdate) AddNillableInt8(i int8) *FieldTypeUpdate { - if ftu.addnillable_int8 == nil { - ftu.addnillable_int8 = &i - } else { - *ftu.addnillable_int8 += i - } + ftu.mutation.AddNillableInt8(i) return ftu } // ClearNillableInt8 clears the value of nillable_int8. func (ftu *FieldTypeUpdate) ClearNillableInt8() *FieldTypeUpdate { - ftu.nillable_int8 = nil - ftu.clearnillable_int8 = true + ftu.mutation.ClearNillableInt8() return ftu } // SetNillableInt16 sets the nillable_int16 field. func (ftu *FieldTypeUpdate) SetNillableInt16(i int16) *FieldTypeUpdate { - ftu.nillable_int16 = &i - ftu.addnillable_int16 = nil + ftu.mutation.ResetNillableInt16() + ftu.mutation.SetNillableInt16(i) return ftu } @@ -421,25 +302,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt16(i *int16) *FieldTypeUpdate // AddNillableInt16 adds i to nillable_int16. func (ftu *FieldTypeUpdate) AddNillableInt16(i int16) *FieldTypeUpdate { - if ftu.addnillable_int16 == nil { - ftu.addnillable_int16 = &i - } else { - *ftu.addnillable_int16 += i - } + ftu.mutation.AddNillableInt16(i) return ftu } // ClearNillableInt16 clears the value of nillable_int16. func (ftu *FieldTypeUpdate) ClearNillableInt16() *FieldTypeUpdate { - ftu.nillable_int16 = nil - ftu.clearnillable_int16 = true + ftu.mutation.ClearNillableInt16() return ftu } // SetNillableInt32 sets the nillable_int32 field. func (ftu *FieldTypeUpdate) SetNillableInt32(i int32) *FieldTypeUpdate { - ftu.nillable_int32 = &i - ftu.addnillable_int32 = nil + ftu.mutation.ResetNillableInt32() + ftu.mutation.SetNillableInt32(i) return ftu } @@ -453,25 +329,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt32(i *int32) *FieldTypeUpdate // AddNillableInt32 adds i to nillable_int32. func (ftu *FieldTypeUpdate) AddNillableInt32(i int32) *FieldTypeUpdate { - if ftu.addnillable_int32 == nil { - ftu.addnillable_int32 = &i - } else { - *ftu.addnillable_int32 += i - } + ftu.mutation.AddNillableInt32(i) return ftu } // ClearNillableInt32 clears the value of nillable_int32. func (ftu *FieldTypeUpdate) ClearNillableInt32() *FieldTypeUpdate { - ftu.nillable_int32 = nil - ftu.clearnillable_int32 = true + ftu.mutation.ClearNillableInt32() return ftu } // SetNillableInt64 sets the nillable_int64 field. func (ftu *FieldTypeUpdate) SetNillableInt64(i int64) *FieldTypeUpdate { - ftu.nillable_int64 = &i - ftu.addnillable_int64 = nil + ftu.mutation.ResetNillableInt64() + ftu.mutation.SetNillableInt64(i) return ftu } @@ -485,25 +356,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt64(i *int64) *FieldTypeUpdate // AddNillableInt64 adds i to nillable_int64. func (ftu *FieldTypeUpdate) AddNillableInt64(i int64) *FieldTypeUpdate { - if ftu.addnillable_int64 == nil { - ftu.addnillable_int64 = &i - } else { - *ftu.addnillable_int64 += i - } + ftu.mutation.AddNillableInt64(i) return ftu } // ClearNillableInt64 clears the value of nillable_int64. func (ftu *FieldTypeUpdate) ClearNillableInt64() *FieldTypeUpdate { - ftu.nillable_int64 = nil - ftu.clearnillable_int64 = true + ftu.mutation.ClearNillableInt64() return ftu } // SetValidateOptionalInt32 sets the validate_optional_int32 field. func (ftu *FieldTypeUpdate) SetValidateOptionalInt32(i int32) *FieldTypeUpdate { - ftu.validate_optional_int32 = &i - ftu.addvalidate_optional_int32 = nil + ftu.mutation.ResetValidateOptionalInt32() + ftu.mutation.SetValidateOptionalInt32(i) return ftu } @@ -517,25 +383,20 @@ func (ftu *FieldTypeUpdate) SetNillableValidateOptionalInt32(i *int32) *FieldTyp // AddValidateOptionalInt32 adds i to validate_optional_int32. func (ftu *FieldTypeUpdate) AddValidateOptionalInt32(i int32) *FieldTypeUpdate { - if ftu.addvalidate_optional_int32 == nil { - ftu.addvalidate_optional_int32 = &i - } else { - *ftu.addvalidate_optional_int32 += i - } + ftu.mutation.AddValidateOptionalInt32(i) return ftu } // ClearValidateOptionalInt32 clears the value of validate_optional_int32. func (ftu *FieldTypeUpdate) ClearValidateOptionalInt32() *FieldTypeUpdate { - ftu.validate_optional_int32 = nil - ftu.clearvalidate_optional_int32 = true + ftu.mutation.ClearValidateOptionalInt32() return ftu } // SetOptionalUint sets the optional_uint field. func (ftu *FieldTypeUpdate) SetOptionalUint(u uint) *FieldTypeUpdate { - ftu.optional_uint = &u - ftu.addoptional_uint = nil + ftu.mutation.ResetOptionalUint() + ftu.mutation.SetOptionalUint(u) return ftu } @@ -549,25 +410,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint(u *uint) *FieldTypeUpdate { // AddOptionalUint adds u to optional_uint. func (ftu *FieldTypeUpdate) AddOptionalUint(u uint) *FieldTypeUpdate { - if ftu.addoptional_uint == nil { - ftu.addoptional_uint = &u - } else { - *ftu.addoptional_uint += u - } + ftu.mutation.AddOptionalUint(u) return ftu } // ClearOptionalUint clears the value of optional_uint. func (ftu *FieldTypeUpdate) ClearOptionalUint() *FieldTypeUpdate { - ftu.optional_uint = nil - ftu.clearoptional_uint = true + ftu.mutation.ClearOptionalUint() return ftu } // SetOptionalUint8 sets the optional_uint8 field. func (ftu *FieldTypeUpdate) SetOptionalUint8(u uint8) *FieldTypeUpdate { - ftu.optional_uint8 = &u - ftu.addoptional_uint8 = nil + ftu.mutation.ResetOptionalUint8() + ftu.mutation.SetOptionalUint8(u) return ftu } @@ -581,25 +437,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint8(u *uint8) *FieldTypeUpdate // AddOptionalUint8 adds u to optional_uint8. func (ftu *FieldTypeUpdate) AddOptionalUint8(u uint8) *FieldTypeUpdate { - if ftu.addoptional_uint8 == nil { - ftu.addoptional_uint8 = &u - } else { - *ftu.addoptional_uint8 += u - } + ftu.mutation.AddOptionalUint8(u) return ftu } // ClearOptionalUint8 clears the value of optional_uint8. func (ftu *FieldTypeUpdate) ClearOptionalUint8() *FieldTypeUpdate { - ftu.optional_uint8 = nil - ftu.clearoptional_uint8 = true + ftu.mutation.ClearOptionalUint8() return ftu } // SetOptionalUint16 sets the optional_uint16 field. func (ftu *FieldTypeUpdate) SetOptionalUint16(u uint16) *FieldTypeUpdate { - ftu.optional_uint16 = &u - ftu.addoptional_uint16 = nil + ftu.mutation.ResetOptionalUint16() + ftu.mutation.SetOptionalUint16(u) return ftu } @@ -613,25 +464,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint16(u *uint16) *FieldTypeUpdat // AddOptionalUint16 adds u to optional_uint16. func (ftu *FieldTypeUpdate) AddOptionalUint16(u uint16) *FieldTypeUpdate { - if ftu.addoptional_uint16 == nil { - ftu.addoptional_uint16 = &u - } else { - *ftu.addoptional_uint16 += u - } + ftu.mutation.AddOptionalUint16(u) return ftu } // ClearOptionalUint16 clears the value of optional_uint16. func (ftu *FieldTypeUpdate) ClearOptionalUint16() *FieldTypeUpdate { - ftu.optional_uint16 = nil - ftu.clearoptional_uint16 = true + ftu.mutation.ClearOptionalUint16() return ftu } // SetOptionalUint32 sets the optional_uint32 field. func (ftu *FieldTypeUpdate) SetOptionalUint32(u uint32) *FieldTypeUpdate { - ftu.optional_uint32 = &u - ftu.addoptional_uint32 = nil + ftu.mutation.ResetOptionalUint32() + ftu.mutation.SetOptionalUint32(u) return ftu } @@ -645,25 +491,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint32(u *uint32) *FieldTypeUpdat // AddOptionalUint32 adds u to optional_uint32. func (ftu *FieldTypeUpdate) AddOptionalUint32(u uint32) *FieldTypeUpdate { - if ftu.addoptional_uint32 == nil { - ftu.addoptional_uint32 = &u - } else { - *ftu.addoptional_uint32 += u - } + ftu.mutation.AddOptionalUint32(u) return ftu } // ClearOptionalUint32 clears the value of optional_uint32. func (ftu *FieldTypeUpdate) ClearOptionalUint32() *FieldTypeUpdate { - ftu.optional_uint32 = nil - ftu.clearoptional_uint32 = true + ftu.mutation.ClearOptionalUint32() return ftu } // SetOptionalUint64 sets the optional_uint64 field. func (ftu *FieldTypeUpdate) SetOptionalUint64(u uint64) *FieldTypeUpdate { - ftu.optional_uint64 = &u - ftu.addoptional_uint64 = nil + ftu.mutation.ResetOptionalUint64() + ftu.mutation.SetOptionalUint64(u) return ftu } @@ -677,24 +518,19 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint64(u *uint64) *FieldTypeUpdat // AddOptionalUint64 adds u to optional_uint64. func (ftu *FieldTypeUpdate) AddOptionalUint64(u uint64) *FieldTypeUpdate { - if ftu.addoptional_uint64 == nil { - ftu.addoptional_uint64 = &u - } else { - *ftu.addoptional_uint64 += u - } + ftu.mutation.AddOptionalUint64(u) return ftu } // ClearOptionalUint64 clears the value of optional_uint64. func (ftu *FieldTypeUpdate) ClearOptionalUint64() *FieldTypeUpdate { - ftu.optional_uint64 = nil - ftu.clearoptional_uint64 = true + ftu.mutation.ClearOptionalUint64() return ftu } // SetState sets the state field. func (ftu *FieldTypeUpdate) SetState(f fieldtype.State) *FieldTypeUpdate { - ftu.state = &f + ftu.mutation.SetState(f) return ftu } @@ -708,15 +544,14 @@ func (ftu *FieldTypeUpdate) SetNillableState(f *fieldtype.State) *FieldTypeUpdat // ClearState clears the value of state. func (ftu *FieldTypeUpdate) ClearState() *FieldTypeUpdate { - ftu.state = nil - ftu.clearstate = true + ftu.mutation.ClearState() return ftu } // SetOptionalFloat sets the optional_float field. func (ftu *FieldTypeUpdate) SetOptionalFloat(f float64) *FieldTypeUpdate { - ftu.optional_float = &f - ftu.addoptional_float = nil + ftu.mutation.ResetOptionalFloat() + ftu.mutation.SetOptionalFloat(f) return ftu } @@ -730,25 +565,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalFloat(f *float64) *FieldTypeUpdat // AddOptionalFloat adds f to optional_float. func (ftu *FieldTypeUpdate) AddOptionalFloat(f float64) *FieldTypeUpdate { - if ftu.addoptional_float == nil { - ftu.addoptional_float = &f - } else { - *ftu.addoptional_float += f - } + ftu.mutation.AddOptionalFloat(f) return ftu } // ClearOptionalFloat clears the value of optional_float. func (ftu *FieldTypeUpdate) ClearOptionalFloat() *FieldTypeUpdate { - ftu.optional_float = nil - ftu.clearoptional_float = true + ftu.mutation.ClearOptionalFloat() return ftu } // SetOptionalFloat32 sets the optional_float32 field. func (ftu *FieldTypeUpdate) SetOptionalFloat32(f float32) *FieldTypeUpdate { - ftu.optional_float32 = &f - ftu.addoptional_float32 = nil + ftu.mutation.ResetOptionalFloat32() + ftu.mutation.SetOptionalFloat32(f) return ftu } @@ -762,34 +592,52 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalFloat32(f *float32) *FieldTypeUpd // AddOptionalFloat32 adds f to optional_float32. func (ftu *FieldTypeUpdate) AddOptionalFloat32(f float32) *FieldTypeUpdate { - if ftu.addoptional_float32 == nil { - ftu.addoptional_float32 = &f - } else { - *ftu.addoptional_float32 += f - } + ftu.mutation.AddOptionalFloat32(f) return ftu } // ClearOptionalFloat32 clears the value of optional_float32. func (ftu *FieldTypeUpdate) ClearOptionalFloat32() *FieldTypeUpdate { - ftu.optional_float32 = nil - ftu.clearoptional_float32 = true + ftu.mutation.ClearOptionalFloat32() return ftu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (ftu *FieldTypeUpdate) Save(ctx context.Context) (int, error) { - if ftu.validate_optional_int32 != nil { - if err := fieldtype.ValidateOptionalInt32Validator(*ftu.validate_optional_int32); err != nil { + if v, ok := ftu.mutation.ValidateOptionalInt32(); ok { + if err := fieldtype.ValidateOptionalInt32Validator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"validate_optional_int32\": %v", err) } } - if ftu.state != nil { - if err := fieldtype.StateValidator(*ftu.state); err != nil { + if v, ok := ftu.mutation.State(); ok { + if err := fieldtype.StateValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"state\": %v", err) } } - return ftu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(ftu.hooks) == 0 { + affected, err = ftu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftu.mutation = mutation + affected, err = ftu.sqlSave(ctx) + return affected, err + }) + for i := len(ftu.hooks); i > 0; i-- { + mut = ftu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -832,444 +680,444 @@ func (ftu *FieldTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := ftu.int; value != nil { + if value, ok := ftu.mutation.Int(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldInt, }) } - if value := ftu.addint; value != nil { + if value, ok := ftu.mutation.AddedInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldInt, }) } - if value := ftu.int8; value != nil { + if value, ok := ftu.mutation.Int8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldInt8, }) } - if value := ftu.addint8; value != nil { + if value, ok := ftu.mutation.AddedInt8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldInt8, }) } - if value := ftu.int16; value != nil { + if value, ok := ftu.mutation.Int16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldInt16, }) } - if value := ftu.addint16; value != nil { + if value, ok := ftu.mutation.AddedInt16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldInt16, }) } - if value := ftu.int32; value != nil { + if value, ok := ftu.mutation.Int32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldInt32, }) } - if value := ftu.addint32; value != nil { + if value, ok := ftu.mutation.AddedInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldInt32, }) } - if value := ftu.int64; value != nil { + if value, ok := ftu.mutation.Int64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldInt64, }) } - if value := ftu.addint64; value != nil { + if value, ok := ftu.mutation.AddedInt64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldInt64, }) } - if value := ftu.optional_int; value != nil { + if value, ok := ftu.mutation.OptionalInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt, }) } - if value := ftu.addoptional_int; value != nil { + if value, ok := ftu.mutation.AddedOptionalInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt, }) } - if ftu.clearoptional_int { + if ftu.mutation.OptionalIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: fieldtype.FieldOptionalInt, }) } - if value := ftu.optional_int8; value != nil { + if value, ok := ftu.mutation.OptionalInt8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt8, }) } - if value := ftu.addoptional_int8; value != nil { + if value, ok := ftu.mutation.AddedOptionalInt8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt8, }) } - if ftu.clearoptional_int8 { + if ftu.mutation.OptionalInt8Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt8, Column: fieldtype.FieldOptionalInt8, }) } - if value := ftu.optional_int16; value != nil { + if value, ok := ftu.mutation.OptionalInt16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt16, }) } - if value := ftu.addoptional_int16; value != nil { + if value, ok := ftu.mutation.AddedOptionalInt16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt16, }) } - if ftu.clearoptional_int16 { + if ftu.mutation.OptionalInt16Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt16, Column: fieldtype.FieldOptionalInt16, }) } - if value := ftu.optional_int32; value != nil { + if value, ok := ftu.mutation.OptionalInt32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt32, }) } - if value := ftu.addoptional_int32; value != nil { + if value, ok := ftu.mutation.AddedOptionalInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt32, }) } - if ftu.clearoptional_int32 { + if ftu.mutation.OptionalInt32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt32, Column: fieldtype.FieldOptionalInt32, }) } - if value := ftu.optional_int64; value != nil { + if value, ok := ftu.mutation.OptionalInt64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt64, }) } - if value := ftu.addoptional_int64; value != nil { + if value, ok := ftu.mutation.AddedOptionalInt64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt64, }) } - if ftu.clearoptional_int64 { + if ftu.mutation.OptionalInt64Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt64, Column: fieldtype.FieldOptionalInt64, }) } - if value := ftu.nillable_int; value != nil { + if value, ok := ftu.mutation.NillableInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt, }) } - if value := ftu.addnillable_int; value != nil { + if value, ok := ftu.mutation.AddedNillableInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt, }) } - if ftu.clearnillable_int { + if ftu.mutation.NillableIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: fieldtype.FieldNillableInt, }) } - if value := ftu.nillable_int8; value != nil { + if value, ok := ftu.mutation.NillableInt8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt8, }) } - if value := ftu.addnillable_int8; value != nil { + if value, ok := ftu.mutation.AddedNillableInt8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt8, }) } - if ftu.clearnillable_int8 { + if ftu.mutation.NillableInt8Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt8, Column: fieldtype.FieldNillableInt8, }) } - if value := ftu.nillable_int16; value != nil { + if value, ok := ftu.mutation.NillableInt16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt16, }) } - if value := ftu.addnillable_int16; value != nil { + if value, ok := ftu.mutation.AddedNillableInt16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt16, }) } - if ftu.clearnillable_int16 { + if ftu.mutation.NillableInt16Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt16, Column: fieldtype.FieldNillableInt16, }) } - if value := ftu.nillable_int32; value != nil { + if value, ok := ftu.mutation.NillableInt32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt32, }) } - if value := ftu.addnillable_int32; value != nil { + if value, ok := ftu.mutation.AddedNillableInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt32, }) } - if ftu.clearnillable_int32 { + if ftu.mutation.NillableInt32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt32, Column: fieldtype.FieldNillableInt32, }) } - if value := ftu.nillable_int64; value != nil { + if value, ok := ftu.mutation.NillableInt64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt64, }) } - if value := ftu.addnillable_int64; value != nil { + if value, ok := ftu.mutation.AddedNillableInt64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt64, }) } - if ftu.clearnillable_int64 { + if ftu.mutation.NillableInt64Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt64, Column: fieldtype.FieldNillableInt64, }) } - if value := ftu.validate_optional_int32; value != nil { + if value, ok := ftu.mutation.ValidateOptionalInt32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldValidateOptionalInt32, }) } - if value := ftu.addvalidate_optional_int32; value != nil { + if value, ok := ftu.mutation.AddedValidateOptionalInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldValidateOptionalInt32, }) } - if ftu.clearvalidate_optional_int32 { + if ftu.mutation.ValidateOptionalInt32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt32, Column: fieldtype.FieldValidateOptionalInt32, }) } - if value := ftu.optional_uint; value != nil { + if value, ok := ftu.mutation.OptionalUint(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint, }) } - if value := ftu.addoptional_uint; value != nil { + if value, ok := ftu.mutation.AddedOptionalUint(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint, }) } - if ftu.clearoptional_uint { + if ftu.mutation.OptionalUintCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint, Column: fieldtype.FieldOptionalUint, }) } - if value := ftu.optional_uint8; value != nil { + if value, ok := ftu.mutation.OptionalUint8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint8, }) } - if value := ftu.addoptional_uint8; value != nil { + if value, ok := ftu.mutation.AddedOptionalUint8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint8, }) } - if ftu.clearoptional_uint8 { + if ftu.mutation.OptionalUint8Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint8, Column: fieldtype.FieldOptionalUint8, }) } - if value := ftu.optional_uint16; value != nil { + if value, ok := ftu.mutation.OptionalUint16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint16, }) } - if value := ftu.addoptional_uint16; value != nil { + if value, ok := ftu.mutation.AddedOptionalUint16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint16, }) } - if ftu.clearoptional_uint16 { + if ftu.mutation.OptionalUint16Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint16, Column: fieldtype.FieldOptionalUint16, }) } - if value := ftu.optional_uint32; value != nil { + if value, ok := ftu.mutation.OptionalUint32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint32, }) } - if value := ftu.addoptional_uint32; value != nil { + if value, ok := ftu.mutation.AddedOptionalUint32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint32, }) } - if ftu.clearoptional_uint32 { + if ftu.mutation.OptionalUint32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint32, Column: fieldtype.FieldOptionalUint32, }) } - if value := ftu.optional_uint64; value != nil { + if value, ok := ftu.mutation.OptionalUint64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint64, }) } - if value := ftu.addoptional_uint64; value != nil { + if value, ok := ftu.mutation.AddedOptionalUint64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint64, }) } - if ftu.clearoptional_uint64 { + if ftu.mutation.OptionalUint64Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint64, Column: fieldtype.FieldOptionalUint64, }) } - if value := ftu.state; value != nil { + if value, ok := ftu.mutation.State(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: fieldtype.FieldState, }) } - if ftu.clearstate { + if ftu.mutation.StateCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeEnum, Column: fieldtype.FieldState, }) } - if value := ftu.optional_float; value != nil { + if value, ok := ftu.mutation.OptionalFloat(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat, }) } - if value := ftu.addoptional_float; value != nil { + if value, ok := ftu.mutation.AddedOptionalFloat(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat, }) } - if ftu.clearoptional_float { + if ftu.mutation.OptionalFloatCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, Column: fieldtype.FieldOptionalFloat, }) } - if value := ftu.optional_float32; value != nil { + if value, ok := ftu.mutation.OptionalFloat32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat32, }) } - if value := ftu.addoptional_float32; value != nil { + if value, ok := ftu.mutation.AddedOptionalFloat32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat32, }) } - if ftu.clearoptional_float32 { + if ftu.mutation.OptionalFloat32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, Column: fieldtype.FieldOptionalFloat32, @@ -1289,164 +1137,79 @@ func (ftu *FieldTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { // FieldTypeUpdateOne is the builder for updating a single FieldType entity. type FieldTypeUpdateOne struct { config - id string - int *int - addint *int - int8 *int8 - addint8 *int8 - int16 *int16 - addint16 *int16 - int32 *int32 - addint32 *int32 - int64 *int64 - addint64 *int64 - optional_int *int - addoptional_int *int - clearoptional_int bool - optional_int8 *int8 - addoptional_int8 *int8 - clearoptional_int8 bool - optional_int16 *int16 - addoptional_int16 *int16 - clearoptional_int16 bool - optional_int32 *int32 - addoptional_int32 *int32 - clearoptional_int32 bool - optional_int64 *int64 - addoptional_int64 *int64 - clearoptional_int64 bool - nillable_int *int - addnillable_int *int - clearnillable_int bool - nillable_int8 *int8 - addnillable_int8 *int8 - clearnillable_int8 bool - nillable_int16 *int16 - addnillable_int16 *int16 - clearnillable_int16 bool - nillable_int32 *int32 - addnillable_int32 *int32 - clearnillable_int32 bool - nillable_int64 *int64 - addnillable_int64 *int64 - clearnillable_int64 bool - validate_optional_int32 *int32 - addvalidate_optional_int32 *int32 - clearvalidate_optional_int32 bool - optional_uint *uint - addoptional_uint *uint - clearoptional_uint bool - optional_uint8 *uint8 - addoptional_uint8 *uint8 - clearoptional_uint8 bool - optional_uint16 *uint16 - addoptional_uint16 *uint16 - clearoptional_uint16 bool - optional_uint32 *uint32 - addoptional_uint32 *uint32 - clearoptional_uint32 bool - optional_uint64 *uint64 - addoptional_uint64 *uint64 - clearoptional_uint64 bool - state *fieldtype.State - clearstate bool - optional_float *float64 - addoptional_float *float64 - clearoptional_float bool - optional_float32 *float32 - addoptional_float32 *float32 - clearoptional_float32 bool + hooks []Hook + mutation *FieldTypeMutation } // SetInt sets the int field. func (ftuo *FieldTypeUpdateOne) SetInt(i int) *FieldTypeUpdateOne { - ftuo.int = &i - ftuo.addint = nil + ftuo.mutation.ResetInt() + ftuo.mutation.SetInt(i) return ftuo } // AddInt adds i to int. func (ftuo *FieldTypeUpdateOne) AddInt(i int) *FieldTypeUpdateOne { - if ftuo.addint == nil { - ftuo.addint = &i - } else { - *ftuo.addint += i - } + ftuo.mutation.AddInt(i) return ftuo } // SetInt8 sets the int8 field. func (ftuo *FieldTypeUpdateOne) SetInt8(i int8) *FieldTypeUpdateOne { - ftuo.int8 = &i - ftuo.addint8 = nil + ftuo.mutation.ResetInt8() + ftuo.mutation.SetInt8(i) return ftuo } // AddInt8 adds i to int8. func (ftuo *FieldTypeUpdateOne) AddInt8(i int8) *FieldTypeUpdateOne { - if ftuo.addint8 == nil { - ftuo.addint8 = &i - } else { - *ftuo.addint8 += i - } + ftuo.mutation.AddInt8(i) return ftuo } // SetInt16 sets the int16 field. func (ftuo *FieldTypeUpdateOne) SetInt16(i int16) *FieldTypeUpdateOne { - ftuo.int16 = &i - ftuo.addint16 = nil + ftuo.mutation.ResetInt16() + ftuo.mutation.SetInt16(i) return ftuo } // AddInt16 adds i to int16. func (ftuo *FieldTypeUpdateOne) AddInt16(i int16) *FieldTypeUpdateOne { - if ftuo.addint16 == nil { - ftuo.addint16 = &i - } else { - *ftuo.addint16 += i - } + ftuo.mutation.AddInt16(i) return ftuo } // SetInt32 sets the int32 field. func (ftuo *FieldTypeUpdateOne) SetInt32(i int32) *FieldTypeUpdateOne { - ftuo.int32 = &i - ftuo.addint32 = nil + ftuo.mutation.ResetInt32() + ftuo.mutation.SetInt32(i) return ftuo } // AddInt32 adds i to int32. func (ftuo *FieldTypeUpdateOne) AddInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addint32 == nil { - ftuo.addint32 = &i - } else { - *ftuo.addint32 += i - } + ftuo.mutation.AddInt32(i) return ftuo } // SetInt64 sets the int64 field. func (ftuo *FieldTypeUpdateOne) SetInt64(i int64) *FieldTypeUpdateOne { - ftuo.int64 = &i - ftuo.addint64 = nil + ftuo.mutation.ResetInt64() + ftuo.mutation.SetInt64(i) return ftuo } // AddInt64 adds i to int64. func (ftuo *FieldTypeUpdateOne) AddInt64(i int64) *FieldTypeUpdateOne { - if ftuo.addint64 == nil { - ftuo.addint64 = &i - } else { - *ftuo.addint64 += i - } + ftuo.mutation.AddInt64(i) return ftuo } // SetOptionalInt sets the optional_int field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt(i int) *FieldTypeUpdateOne { - ftuo.optional_int = &i - ftuo.addoptional_int = nil + ftuo.mutation.ResetOptionalInt() + ftuo.mutation.SetOptionalInt(i) return ftuo } @@ -1460,25 +1223,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt(i *int) *FieldTypeUpdateO // AddOptionalInt adds i to optional_int. func (ftuo *FieldTypeUpdateOne) AddOptionalInt(i int) *FieldTypeUpdateOne { - if ftuo.addoptional_int == nil { - ftuo.addoptional_int = &i - } else { - *ftuo.addoptional_int += i - } + ftuo.mutation.AddOptionalInt(i) return ftuo } // ClearOptionalInt clears the value of optional_int. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt() *FieldTypeUpdateOne { - ftuo.optional_int = nil - ftuo.clearoptional_int = true + ftuo.mutation.ClearOptionalInt() return ftuo } // SetOptionalInt8 sets the optional_int8 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt8(i int8) *FieldTypeUpdateOne { - ftuo.optional_int8 = &i - ftuo.addoptional_int8 = nil + ftuo.mutation.ResetOptionalInt8() + ftuo.mutation.SetOptionalInt8(i) return ftuo } @@ -1492,25 +1250,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt8(i *int8) *FieldTypeUpdat // AddOptionalInt8 adds i to optional_int8. func (ftuo *FieldTypeUpdateOne) AddOptionalInt8(i int8) *FieldTypeUpdateOne { - if ftuo.addoptional_int8 == nil { - ftuo.addoptional_int8 = &i - } else { - *ftuo.addoptional_int8 += i - } + ftuo.mutation.AddOptionalInt8(i) return ftuo } // ClearOptionalInt8 clears the value of optional_int8. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt8() *FieldTypeUpdateOne { - ftuo.optional_int8 = nil - ftuo.clearoptional_int8 = true + ftuo.mutation.ClearOptionalInt8() return ftuo } // SetOptionalInt16 sets the optional_int16 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt16(i int16) *FieldTypeUpdateOne { - ftuo.optional_int16 = &i - ftuo.addoptional_int16 = nil + ftuo.mutation.ResetOptionalInt16() + ftuo.mutation.SetOptionalInt16(i) return ftuo } @@ -1524,25 +1277,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt16(i *int16) *FieldTypeUpd // AddOptionalInt16 adds i to optional_int16. func (ftuo *FieldTypeUpdateOne) AddOptionalInt16(i int16) *FieldTypeUpdateOne { - if ftuo.addoptional_int16 == nil { - ftuo.addoptional_int16 = &i - } else { - *ftuo.addoptional_int16 += i - } + ftuo.mutation.AddOptionalInt16(i) return ftuo } // ClearOptionalInt16 clears the value of optional_int16. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt16() *FieldTypeUpdateOne { - ftuo.optional_int16 = nil - ftuo.clearoptional_int16 = true + ftuo.mutation.ClearOptionalInt16() return ftuo } // SetOptionalInt32 sets the optional_int32 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt32(i int32) *FieldTypeUpdateOne { - ftuo.optional_int32 = &i - ftuo.addoptional_int32 = nil + ftuo.mutation.ResetOptionalInt32() + ftuo.mutation.SetOptionalInt32(i) return ftuo } @@ -1556,25 +1304,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt32(i *int32) *FieldTypeUpd // AddOptionalInt32 adds i to optional_int32. func (ftuo *FieldTypeUpdateOne) AddOptionalInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addoptional_int32 == nil { - ftuo.addoptional_int32 = &i - } else { - *ftuo.addoptional_int32 += i - } + ftuo.mutation.AddOptionalInt32(i) return ftuo } // ClearOptionalInt32 clears the value of optional_int32. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt32() *FieldTypeUpdateOne { - ftuo.optional_int32 = nil - ftuo.clearoptional_int32 = true + ftuo.mutation.ClearOptionalInt32() return ftuo } // SetOptionalInt64 sets the optional_int64 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt64(i int64) *FieldTypeUpdateOne { - ftuo.optional_int64 = &i - ftuo.addoptional_int64 = nil + ftuo.mutation.ResetOptionalInt64() + ftuo.mutation.SetOptionalInt64(i) return ftuo } @@ -1588,25 +1331,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt64(i *int64) *FieldTypeUpd // AddOptionalInt64 adds i to optional_int64. func (ftuo *FieldTypeUpdateOne) AddOptionalInt64(i int64) *FieldTypeUpdateOne { - if ftuo.addoptional_int64 == nil { - ftuo.addoptional_int64 = &i - } else { - *ftuo.addoptional_int64 += i - } + ftuo.mutation.AddOptionalInt64(i) return ftuo } // ClearOptionalInt64 clears the value of optional_int64. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt64() *FieldTypeUpdateOne { - ftuo.optional_int64 = nil - ftuo.clearoptional_int64 = true + ftuo.mutation.ClearOptionalInt64() return ftuo } // SetNillableInt sets the nillable_int field. func (ftuo *FieldTypeUpdateOne) SetNillableInt(i int) *FieldTypeUpdateOne { - ftuo.nillable_int = &i - ftuo.addnillable_int = nil + ftuo.mutation.ResetNillableInt() + ftuo.mutation.SetNillableInt(i) return ftuo } @@ -1620,25 +1358,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt(i *int) *FieldTypeUpdateO // AddNillableInt adds i to nillable_int. func (ftuo *FieldTypeUpdateOne) AddNillableInt(i int) *FieldTypeUpdateOne { - if ftuo.addnillable_int == nil { - ftuo.addnillable_int = &i - } else { - *ftuo.addnillable_int += i - } + ftuo.mutation.AddNillableInt(i) return ftuo } // ClearNillableInt clears the value of nillable_int. func (ftuo *FieldTypeUpdateOne) ClearNillableInt() *FieldTypeUpdateOne { - ftuo.nillable_int = nil - ftuo.clearnillable_int = true + ftuo.mutation.ClearNillableInt() return ftuo } // SetNillableInt8 sets the nillable_int8 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt8(i int8) *FieldTypeUpdateOne { - ftuo.nillable_int8 = &i - ftuo.addnillable_int8 = nil + ftuo.mutation.ResetNillableInt8() + ftuo.mutation.SetNillableInt8(i) return ftuo } @@ -1652,25 +1385,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt8(i *int8) *FieldTypeUpdat // AddNillableInt8 adds i to nillable_int8. func (ftuo *FieldTypeUpdateOne) AddNillableInt8(i int8) *FieldTypeUpdateOne { - if ftuo.addnillable_int8 == nil { - ftuo.addnillable_int8 = &i - } else { - *ftuo.addnillable_int8 += i - } + ftuo.mutation.AddNillableInt8(i) return ftuo } // ClearNillableInt8 clears the value of nillable_int8. func (ftuo *FieldTypeUpdateOne) ClearNillableInt8() *FieldTypeUpdateOne { - ftuo.nillable_int8 = nil - ftuo.clearnillable_int8 = true + ftuo.mutation.ClearNillableInt8() return ftuo } // SetNillableInt16 sets the nillable_int16 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt16(i int16) *FieldTypeUpdateOne { - ftuo.nillable_int16 = &i - ftuo.addnillable_int16 = nil + ftuo.mutation.ResetNillableInt16() + ftuo.mutation.SetNillableInt16(i) return ftuo } @@ -1684,25 +1412,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt16(i *int16) *FieldTypeUpd // AddNillableInt16 adds i to nillable_int16. func (ftuo *FieldTypeUpdateOne) AddNillableInt16(i int16) *FieldTypeUpdateOne { - if ftuo.addnillable_int16 == nil { - ftuo.addnillable_int16 = &i - } else { - *ftuo.addnillable_int16 += i - } + ftuo.mutation.AddNillableInt16(i) return ftuo } // ClearNillableInt16 clears the value of nillable_int16. func (ftuo *FieldTypeUpdateOne) ClearNillableInt16() *FieldTypeUpdateOne { - ftuo.nillable_int16 = nil - ftuo.clearnillable_int16 = true + ftuo.mutation.ClearNillableInt16() return ftuo } // SetNillableInt32 sets the nillable_int32 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt32(i int32) *FieldTypeUpdateOne { - ftuo.nillable_int32 = &i - ftuo.addnillable_int32 = nil + ftuo.mutation.ResetNillableInt32() + ftuo.mutation.SetNillableInt32(i) return ftuo } @@ -1716,25 +1439,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt32(i *int32) *FieldTypeUpd // AddNillableInt32 adds i to nillable_int32. func (ftuo *FieldTypeUpdateOne) AddNillableInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addnillable_int32 == nil { - ftuo.addnillable_int32 = &i - } else { - *ftuo.addnillable_int32 += i - } + ftuo.mutation.AddNillableInt32(i) return ftuo } // ClearNillableInt32 clears the value of nillable_int32. func (ftuo *FieldTypeUpdateOne) ClearNillableInt32() *FieldTypeUpdateOne { - ftuo.nillable_int32 = nil - ftuo.clearnillable_int32 = true + ftuo.mutation.ClearNillableInt32() return ftuo } // SetNillableInt64 sets the nillable_int64 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt64(i int64) *FieldTypeUpdateOne { - ftuo.nillable_int64 = &i - ftuo.addnillable_int64 = nil + ftuo.mutation.ResetNillableInt64() + ftuo.mutation.SetNillableInt64(i) return ftuo } @@ -1748,25 +1466,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt64(i *int64) *FieldTypeUpd // AddNillableInt64 adds i to nillable_int64. func (ftuo *FieldTypeUpdateOne) AddNillableInt64(i int64) *FieldTypeUpdateOne { - if ftuo.addnillable_int64 == nil { - ftuo.addnillable_int64 = &i - } else { - *ftuo.addnillable_int64 += i - } + ftuo.mutation.AddNillableInt64(i) return ftuo } // ClearNillableInt64 clears the value of nillable_int64. func (ftuo *FieldTypeUpdateOne) ClearNillableInt64() *FieldTypeUpdateOne { - ftuo.nillable_int64 = nil - ftuo.clearnillable_int64 = true + ftuo.mutation.ClearNillableInt64() return ftuo } // SetValidateOptionalInt32 sets the validate_optional_int32 field. func (ftuo *FieldTypeUpdateOne) SetValidateOptionalInt32(i int32) *FieldTypeUpdateOne { - ftuo.validate_optional_int32 = &i - ftuo.addvalidate_optional_int32 = nil + ftuo.mutation.ResetValidateOptionalInt32() + ftuo.mutation.SetValidateOptionalInt32(i) return ftuo } @@ -1780,25 +1493,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableValidateOptionalInt32(i *int32) *Fiel // AddValidateOptionalInt32 adds i to validate_optional_int32. func (ftuo *FieldTypeUpdateOne) AddValidateOptionalInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addvalidate_optional_int32 == nil { - ftuo.addvalidate_optional_int32 = &i - } else { - *ftuo.addvalidate_optional_int32 += i - } + ftuo.mutation.AddValidateOptionalInt32(i) return ftuo } // ClearValidateOptionalInt32 clears the value of validate_optional_int32. func (ftuo *FieldTypeUpdateOne) ClearValidateOptionalInt32() *FieldTypeUpdateOne { - ftuo.validate_optional_int32 = nil - ftuo.clearvalidate_optional_int32 = true + ftuo.mutation.ClearValidateOptionalInt32() return ftuo } // SetOptionalUint sets the optional_uint field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint(u uint) *FieldTypeUpdateOne { - ftuo.optional_uint = &u - ftuo.addoptional_uint = nil + ftuo.mutation.ResetOptionalUint() + ftuo.mutation.SetOptionalUint(u) return ftuo } @@ -1812,25 +1520,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint(u *uint) *FieldTypeUpdat // AddOptionalUint adds u to optional_uint. func (ftuo *FieldTypeUpdateOne) AddOptionalUint(u uint) *FieldTypeUpdateOne { - if ftuo.addoptional_uint == nil { - ftuo.addoptional_uint = &u - } else { - *ftuo.addoptional_uint += u - } + ftuo.mutation.AddOptionalUint(u) return ftuo } // ClearOptionalUint clears the value of optional_uint. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint() *FieldTypeUpdateOne { - ftuo.optional_uint = nil - ftuo.clearoptional_uint = true + ftuo.mutation.ClearOptionalUint() return ftuo } // SetOptionalUint8 sets the optional_uint8 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint8(u uint8) *FieldTypeUpdateOne { - ftuo.optional_uint8 = &u - ftuo.addoptional_uint8 = nil + ftuo.mutation.ResetOptionalUint8() + ftuo.mutation.SetOptionalUint8(u) return ftuo } @@ -1844,25 +1547,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint8(u *uint8) *FieldTypeUpd // AddOptionalUint8 adds u to optional_uint8. func (ftuo *FieldTypeUpdateOne) AddOptionalUint8(u uint8) *FieldTypeUpdateOne { - if ftuo.addoptional_uint8 == nil { - ftuo.addoptional_uint8 = &u - } else { - *ftuo.addoptional_uint8 += u - } + ftuo.mutation.AddOptionalUint8(u) return ftuo } // ClearOptionalUint8 clears the value of optional_uint8. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint8() *FieldTypeUpdateOne { - ftuo.optional_uint8 = nil - ftuo.clearoptional_uint8 = true + ftuo.mutation.ClearOptionalUint8() return ftuo } // SetOptionalUint16 sets the optional_uint16 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint16(u uint16) *FieldTypeUpdateOne { - ftuo.optional_uint16 = &u - ftuo.addoptional_uint16 = nil + ftuo.mutation.ResetOptionalUint16() + ftuo.mutation.SetOptionalUint16(u) return ftuo } @@ -1876,25 +1574,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint16(u *uint16) *FieldTypeU // AddOptionalUint16 adds u to optional_uint16. func (ftuo *FieldTypeUpdateOne) AddOptionalUint16(u uint16) *FieldTypeUpdateOne { - if ftuo.addoptional_uint16 == nil { - ftuo.addoptional_uint16 = &u - } else { - *ftuo.addoptional_uint16 += u - } + ftuo.mutation.AddOptionalUint16(u) return ftuo } // ClearOptionalUint16 clears the value of optional_uint16. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint16() *FieldTypeUpdateOne { - ftuo.optional_uint16 = nil - ftuo.clearoptional_uint16 = true + ftuo.mutation.ClearOptionalUint16() return ftuo } // SetOptionalUint32 sets the optional_uint32 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint32(u uint32) *FieldTypeUpdateOne { - ftuo.optional_uint32 = &u - ftuo.addoptional_uint32 = nil + ftuo.mutation.ResetOptionalUint32() + ftuo.mutation.SetOptionalUint32(u) return ftuo } @@ -1908,25 +1601,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint32(u *uint32) *FieldTypeU // AddOptionalUint32 adds u to optional_uint32. func (ftuo *FieldTypeUpdateOne) AddOptionalUint32(u uint32) *FieldTypeUpdateOne { - if ftuo.addoptional_uint32 == nil { - ftuo.addoptional_uint32 = &u - } else { - *ftuo.addoptional_uint32 += u - } + ftuo.mutation.AddOptionalUint32(u) return ftuo } // ClearOptionalUint32 clears the value of optional_uint32. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint32() *FieldTypeUpdateOne { - ftuo.optional_uint32 = nil - ftuo.clearoptional_uint32 = true + ftuo.mutation.ClearOptionalUint32() return ftuo } // SetOptionalUint64 sets the optional_uint64 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint64(u uint64) *FieldTypeUpdateOne { - ftuo.optional_uint64 = &u - ftuo.addoptional_uint64 = nil + ftuo.mutation.ResetOptionalUint64() + ftuo.mutation.SetOptionalUint64(u) return ftuo } @@ -1940,24 +1628,19 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint64(u *uint64) *FieldTypeU // AddOptionalUint64 adds u to optional_uint64. func (ftuo *FieldTypeUpdateOne) AddOptionalUint64(u uint64) *FieldTypeUpdateOne { - if ftuo.addoptional_uint64 == nil { - ftuo.addoptional_uint64 = &u - } else { - *ftuo.addoptional_uint64 += u - } + ftuo.mutation.AddOptionalUint64(u) return ftuo } // ClearOptionalUint64 clears the value of optional_uint64. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint64() *FieldTypeUpdateOne { - ftuo.optional_uint64 = nil - ftuo.clearoptional_uint64 = true + ftuo.mutation.ClearOptionalUint64() return ftuo } // SetState sets the state field. func (ftuo *FieldTypeUpdateOne) SetState(f fieldtype.State) *FieldTypeUpdateOne { - ftuo.state = &f + ftuo.mutation.SetState(f) return ftuo } @@ -1971,15 +1654,14 @@ func (ftuo *FieldTypeUpdateOne) SetNillableState(f *fieldtype.State) *FieldTypeU // ClearState clears the value of state. func (ftuo *FieldTypeUpdateOne) ClearState() *FieldTypeUpdateOne { - ftuo.state = nil - ftuo.clearstate = true + ftuo.mutation.ClearState() return ftuo } // SetOptionalFloat sets the optional_float field. func (ftuo *FieldTypeUpdateOne) SetOptionalFloat(f float64) *FieldTypeUpdateOne { - ftuo.optional_float = &f - ftuo.addoptional_float = nil + ftuo.mutation.ResetOptionalFloat() + ftuo.mutation.SetOptionalFloat(f) return ftuo } @@ -1993,25 +1675,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalFloat(f *float64) *FieldTypeU // AddOptionalFloat adds f to optional_float. func (ftuo *FieldTypeUpdateOne) AddOptionalFloat(f float64) *FieldTypeUpdateOne { - if ftuo.addoptional_float == nil { - ftuo.addoptional_float = &f - } else { - *ftuo.addoptional_float += f - } + ftuo.mutation.AddOptionalFloat(f) return ftuo } // ClearOptionalFloat clears the value of optional_float. func (ftuo *FieldTypeUpdateOne) ClearOptionalFloat() *FieldTypeUpdateOne { - ftuo.optional_float = nil - ftuo.clearoptional_float = true + ftuo.mutation.ClearOptionalFloat() return ftuo } // SetOptionalFloat32 sets the optional_float32 field. func (ftuo *FieldTypeUpdateOne) SetOptionalFloat32(f float32) *FieldTypeUpdateOne { - ftuo.optional_float32 = &f - ftuo.addoptional_float32 = nil + ftuo.mutation.ResetOptionalFloat32() + ftuo.mutation.SetOptionalFloat32(f) return ftuo } @@ -2025,34 +1702,52 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalFloat32(f *float32) *FieldTyp // AddOptionalFloat32 adds f to optional_float32. func (ftuo *FieldTypeUpdateOne) AddOptionalFloat32(f float32) *FieldTypeUpdateOne { - if ftuo.addoptional_float32 == nil { - ftuo.addoptional_float32 = &f - } else { - *ftuo.addoptional_float32 += f - } + ftuo.mutation.AddOptionalFloat32(f) return ftuo } // ClearOptionalFloat32 clears the value of optional_float32. func (ftuo *FieldTypeUpdateOne) ClearOptionalFloat32() *FieldTypeUpdateOne { - ftuo.optional_float32 = nil - ftuo.clearoptional_float32 = true + ftuo.mutation.ClearOptionalFloat32() return ftuo } // Save executes the query and returns the updated entity. func (ftuo *FieldTypeUpdateOne) Save(ctx context.Context) (*FieldType, error) { - if ftuo.validate_optional_int32 != nil { - if err := fieldtype.ValidateOptionalInt32Validator(*ftuo.validate_optional_int32); err != nil { + if v, ok := ftuo.mutation.ValidateOptionalInt32(); ok { + if err := fieldtype.ValidateOptionalInt32Validator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"validate_optional_int32\": %v", err) } } - if ftuo.state != nil { - if err := fieldtype.StateValidator(*ftuo.state); err != nil { + if v, ok := ftuo.mutation.State(); ok { + if err := fieldtype.StateValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"state\": %v", err) } } - return ftuo.sqlSave(ctx) + var ( + err error + node *FieldType + ) + if len(ftuo.hooks) == 0 { + node, err = ftuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftuo.mutation = mutation + node, err = ftuo.sqlSave(ctx) + return node, err + }) + for i := len(ftuo.hooks); i > 0; i-- { + mut = ftuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -2083,450 +1778,454 @@ func (ftuo *FieldTypeUpdateOne) sqlSave(ctx context.Context) (ft *FieldType, err Table: fieldtype.Table, Columns: fieldtype.Columns, ID: &sqlgraph.FieldSpec{ - Value: ftuo.id, Type: field.TypeString, Column: fieldtype.FieldID, }, }, } - if value := ftuo.int; value != nil { + id, ok := ftuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing FieldType.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := ftuo.mutation.Int(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldInt, }) } - if value := ftuo.addint; value != nil { + if value, ok := ftuo.mutation.AddedInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldInt, }) } - if value := ftuo.int8; value != nil { + if value, ok := ftuo.mutation.Int8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldInt8, }) } - if value := ftuo.addint8; value != nil { + if value, ok := ftuo.mutation.AddedInt8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldInt8, }) } - if value := ftuo.int16; value != nil { + if value, ok := ftuo.mutation.Int16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldInt16, }) } - if value := ftuo.addint16; value != nil { + if value, ok := ftuo.mutation.AddedInt16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldInt16, }) } - if value := ftuo.int32; value != nil { + if value, ok := ftuo.mutation.Int32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldInt32, }) } - if value := ftuo.addint32; value != nil { + if value, ok := ftuo.mutation.AddedInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldInt32, }) } - if value := ftuo.int64; value != nil { + if value, ok := ftuo.mutation.Int64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldInt64, }) } - if value := ftuo.addint64; value != nil { + if value, ok := ftuo.mutation.AddedInt64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldInt64, }) } - if value := ftuo.optional_int; value != nil { + if value, ok := ftuo.mutation.OptionalInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt, }) } - if value := ftuo.addoptional_int; value != nil { + if value, ok := ftuo.mutation.AddedOptionalInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt, }) } - if ftuo.clearoptional_int { + if ftuo.mutation.OptionalIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: fieldtype.FieldOptionalInt, }) } - if value := ftuo.optional_int8; value != nil { + if value, ok := ftuo.mutation.OptionalInt8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt8, }) } - if value := ftuo.addoptional_int8; value != nil { + if value, ok := ftuo.mutation.AddedOptionalInt8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt8, }) } - if ftuo.clearoptional_int8 { + if ftuo.mutation.OptionalInt8Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt8, Column: fieldtype.FieldOptionalInt8, }) } - if value := ftuo.optional_int16; value != nil { + if value, ok := ftuo.mutation.OptionalInt16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt16, }) } - if value := ftuo.addoptional_int16; value != nil { + if value, ok := ftuo.mutation.AddedOptionalInt16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt16, }) } - if ftuo.clearoptional_int16 { + if ftuo.mutation.OptionalInt16Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt16, Column: fieldtype.FieldOptionalInt16, }) } - if value := ftuo.optional_int32; value != nil { + if value, ok := ftuo.mutation.OptionalInt32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt32, }) } - if value := ftuo.addoptional_int32; value != nil { + if value, ok := ftuo.mutation.AddedOptionalInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt32, }) } - if ftuo.clearoptional_int32 { + if ftuo.mutation.OptionalInt32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt32, Column: fieldtype.FieldOptionalInt32, }) } - if value := ftuo.optional_int64; value != nil { + if value, ok := ftuo.mutation.OptionalInt64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt64, }) } - if value := ftuo.addoptional_int64; value != nil { + if value, ok := ftuo.mutation.AddedOptionalInt64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalInt64, }) } - if ftuo.clearoptional_int64 { + if ftuo.mutation.OptionalInt64Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt64, Column: fieldtype.FieldOptionalInt64, }) } - if value := ftuo.nillable_int; value != nil { + if value, ok := ftuo.mutation.NillableInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt, }) } - if value := ftuo.addnillable_int; value != nil { + if value, ok := ftuo.mutation.AddedNillableInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt, }) } - if ftuo.clearnillable_int { + if ftuo.mutation.NillableIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: fieldtype.FieldNillableInt, }) } - if value := ftuo.nillable_int8; value != nil { + if value, ok := ftuo.mutation.NillableInt8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt8, }) } - if value := ftuo.addnillable_int8; value != nil { + if value, ok := ftuo.mutation.AddedNillableInt8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt8, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt8, }) } - if ftuo.clearnillable_int8 { + if ftuo.mutation.NillableInt8Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt8, Column: fieldtype.FieldNillableInt8, }) } - if value := ftuo.nillable_int16; value != nil { + if value, ok := ftuo.mutation.NillableInt16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt16, }) } - if value := ftuo.addnillable_int16; value != nil { + if value, ok := ftuo.mutation.AddedNillableInt16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt16, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt16, }) } - if ftuo.clearnillable_int16 { + if ftuo.mutation.NillableInt16Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt16, Column: fieldtype.FieldNillableInt16, }) } - if value := ftuo.nillable_int32; value != nil { + if value, ok := ftuo.mutation.NillableInt32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt32, }) } - if value := ftuo.addnillable_int32; value != nil { + if value, ok := ftuo.mutation.AddedNillableInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt32, }) } - if ftuo.clearnillable_int32 { + if ftuo.mutation.NillableInt32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt32, Column: fieldtype.FieldNillableInt32, }) } - if value := ftuo.nillable_int64; value != nil { + if value, ok := ftuo.mutation.NillableInt64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt64, }) } - if value := ftuo.addnillable_int64; value != nil { + if value, ok := ftuo.mutation.AddedNillableInt64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt64, - Value: *value, + Value: value, Column: fieldtype.FieldNillableInt64, }) } - if ftuo.clearnillable_int64 { + if ftuo.mutation.NillableInt64Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt64, Column: fieldtype.FieldNillableInt64, }) } - if value := ftuo.validate_optional_int32; value != nil { + if value, ok := ftuo.mutation.ValidateOptionalInt32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldValidateOptionalInt32, }) } - if value := ftuo.addvalidate_optional_int32; value != nil { + if value, ok := ftuo.mutation.AddedValidateOptionalInt32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: fieldtype.FieldValidateOptionalInt32, }) } - if ftuo.clearvalidate_optional_int32 { + if ftuo.mutation.ValidateOptionalInt32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt32, Column: fieldtype.FieldValidateOptionalInt32, }) } - if value := ftuo.optional_uint; value != nil { + if value, ok := ftuo.mutation.OptionalUint(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint, }) } - if value := ftuo.addoptional_uint; value != nil { + if value, ok := ftuo.mutation.AddedOptionalUint(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint, }) } - if ftuo.clearoptional_uint { + if ftuo.mutation.OptionalUintCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint, Column: fieldtype.FieldOptionalUint, }) } - if value := ftuo.optional_uint8; value != nil { + if value, ok := ftuo.mutation.OptionalUint8(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint8, }) } - if value := ftuo.addoptional_uint8; value != nil { + if value, ok := ftuo.mutation.AddedOptionalUint8(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint8, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint8, }) } - if ftuo.clearoptional_uint8 { + if ftuo.mutation.OptionalUint8Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint8, Column: fieldtype.FieldOptionalUint8, }) } - if value := ftuo.optional_uint16; value != nil { + if value, ok := ftuo.mutation.OptionalUint16(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint16, }) } - if value := ftuo.addoptional_uint16; value != nil { + if value, ok := ftuo.mutation.AddedOptionalUint16(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint16, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint16, }) } - if ftuo.clearoptional_uint16 { + if ftuo.mutation.OptionalUint16Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint16, Column: fieldtype.FieldOptionalUint16, }) } - if value := ftuo.optional_uint32; value != nil { + if value, ok := ftuo.mutation.OptionalUint32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint32, }) } - if value := ftuo.addoptional_uint32; value != nil { + if value, ok := ftuo.mutation.AddedOptionalUint32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint32, }) } - if ftuo.clearoptional_uint32 { + if ftuo.mutation.OptionalUint32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint32, Column: fieldtype.FieldOptionalUint32, }) } - if value := ftuo.optional_uint64; value != nil { + if value, ok := ftuo.mutation.OptionalUint64(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeUint64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint64, }) } - if value := ftuo.addoptional_uint64; value != nil { + if value, ok := ftuo.mutation.AddedOptionalUint64(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeUint64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalUint64, }) } - if ftuo.clearoptional_uint64 { + if ftuo.mutation.OptionalUint64Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeUint64, Column: fieldtype.FieldOptionalUint64, }) } - if value := ftuo.state; value != nil { + if value, ok := ftuo.mutation.State(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: fieldtype.FieldState, }) } - if ftuo.clearstate { + if ftuo.mutation.StateCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeEnum, Column: fieldtype.FieldState, }) } - if value := ftuo.optional_float; value != nil { + if value, ok := ftuo.mutation.OptionalFloat(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat, }) } - if value := ftuo.addoptional_float; value != nil { + if value, ok := ftuo.mutation.AddedOptionalFloat(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat, }) } - if ftuo.clearoptional_float { + if ftuo.mutation.OptionalFloatCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeFloat64, Column: fieldtype.FieldOptionalFloat, }) } - if value := ftuo.optional_float32; value != nil { + if value, ok := ftuo.mutation.OptionalFloat32(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat32, }) } - if value := ftuo.addoptional_float32; value != nil { + if value, ok := ftuo.mutation.AddedOptionalFloat32(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, - Value: *value, + Value: value, Column: fieldtype.FieldOptionalFloat32, }) } - if ftuo.clearoptional_float32 { + if ftuo.mutation.OptionalFloat32Cleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeFloat32, Column: fieldtype.FieldOptionalFloat32, diff --git a/entc/integration/ent/file/file.go b/entc/integration/ent/file/file.go index e1f4c4d1e..ad1c0bffd 100644 --- a/entc/integration/ent/file/file.go +++ b/entc/integration/ent/file/file.go @@ -6,24 +6,21 @@ package file -import ( - "github.com/facebookincubator/ent/entc/integration/ent/schema" -) - const ( // Label holds the string label denoting the file type in the database. Label = "file" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldSize holds the string denoting the size vertex property in the database. - FieldSize = "fsize" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" - // FieldUser holds the string denoting the user vertex property in the database. - FieldUser = "user" - // FieldGroup holds the string denoting the group vertex property in the database. + FieldID = "id" // FieldSize holds the string denoting the size vertex property in the database. + FieldSize = "fsize" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldUser holds the string denoting the user vertex property in the database. + FieldUser = "user" // FieldGroup holds the string denoting the group vertex property in the database. FieldGroup = "group" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // EdgeType holds the string denoting the type edge name in mutations. + EdgeType = "type" + // Table holds the table name of the file in the database. Table = "files" // OwnerTable is the table the holds the owner relation/edge. @@ -59,12 +56,8 @@ var ForeignKeys = []string{ } var ( - fields = schema.File{}.Fields() - - // descSize is the schema descriptor for size field. - descSize = fields[0].Descriptor() // DefaultSize holds the default value on creation for the size field. - DefaultSize = descSize.Default.(int) + DefaultSize int // SizeValidator is a validator for the "size" field. It is called by the builders before save. - SizeValidator = descSize.Validators[0].(func(int) error) + SizeValidator func(int) error ) diff --git a/entc/integration/ent/file_create.go b/entc/integration/ent/file_create.go index b1b05ed8f..bd9cc0219 100644 --- a/entc/integration/ent/file_create.go +++ b/entc/integration/ent/file_create.go @@ -22,17 +22,13 @@ import ( // FileCreate is the builder for creating a File entity. type FileCreate struct { config - size *int - name *string - user *string - group *string - owner map[string]struct{} - _type map[string]struct{} + mutation *FileMutation + hooks []Hook } // SetSize sets the size field. func (fc *FileCreate) SetSize(i int) *FileCreate { - fc.size = &i + fc.mutation.SetSize(i) return fc } @@ -46,13 +42,13 @@ func (fc *FileCreate) SetNillableSize(i *int) *FileCreate { // SetName sets the name field. func (fc *FileCreate) SetName(s string) *FileCreate { - fc.name = &s + fc.mutation.SetName(s) return fc } // SetUser sets the user field. func (fc *FileCreate) SetUser(s string) *FileCreate { - fc.user = &s + fc.mutation.SetUser(s) return fc } @@ -66,7 +62,7 @@ func (fc *FileCreate) SetNillableUser(s *string) *FileCreate { // SetGroup sets the group field. func (fc *FileCreate) SetGroup(s string) *FileCreate { - fc.group = &s + fc.mutation.SetGroup(s) return fc } @@ -80,10 +76,7 @@ func (fc *FileCreate) SetNillableGroup(s *string) *FileCreate { // SetOwnerID sets the owner edge to User by id. func (fc *FileCreate) SetOwnerID(id string) *FileCreate { - if fc.owner == nil { - fc.owner = make(map[string]struct{}) - } - fc.owner[id] = struct{}{} + fc.mutation.SetOwnerID(id) return fc } @@ -102,10 +95,7 @@ func (fc *FileCreate) SetOwner(u *User) *FileCreate { // SetTypeID sets the type edge to FileType by id. func (fc *FileCreate) SetTypeID(id string) *FileCreate { - if fc._type == nil { - fc._type = make(map[string]struct{}) - } - fc._type[id] = struct{}{} + fc.mutation.SetTypeID(id) return fc } @@ -124,23 +114,42 @@ func (fc *FileCreate) SetType(f *FileType) *FileCreate { // Save creates the File in the database. func (fc *FileCreate) Save(ctx context.Context) (*File, error) { - if fc.size == nil { + if _, ok := fc.mutation.Size(); !ok { v := file.DefaultSize - fc.size = &v + fc.mutation.SetSize(v) } - if err := file.SizeValidator(*fc.size); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"size\": %v", err) + if v, ok := fc.mutation.Size(); ok { + if err := file.SizeValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"size\": %v", err) + } } - if fc.name == nil { + if _, ok := fc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(fc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *File + ) + if len(fc.hooks) == 0 { + node, err = fc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fc.mutation = mutation + node, err = fc.sqlSave(ctx) + return node, err + }) + for i := len(fc.hooks); i > 0; i-- { + mut = fc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fc.mutation); err != nil { + return nil, err + } } - if len(fc._type) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"type\"") - } - return fc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -163,39 +172,39 @@ func (fc *FileCreate) sqlSave(ctx context.Context) (*File, error) { }, } ) - if value := fc.size; value != nil { + if value, ok := fc.mutation.Size(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: file.FieldSize, }) - f.Size = *value + f.Size = value } - if value := fc.name; value != nil { + if value, ok := fc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldName, }) - f.Name = *value + f.Name = value } - if value := fc.user; value != nil { + if value, ok := fc.mutation.User(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldUser, }) - f.User = value + f.User = &value } - if value := fc.group; value != nil { + if value, ok := fc.mutation.Group(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldGroup, }) - f.Group = *value + f.Group = value } - if nodes := fc.owner; len(nodes) > 0 { + if nodes := fc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -209,7 +218,7 @@ func (fc *FileCreate) sqlSave(ctx context.Context) (*File, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -218,7 +227,7 @@ func (fc *FileCreate) sqlSave(ctx context.Context) (*File, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := fc._type; len(nodes) > 0 { + if nodes := fc.mutation.TypeIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -232,7 +241,7 @@ func (fc *FileCreate) sqlSave(ctx context.Context) (*File, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/file_delete.go b/entc/integration/ent/file_delete.go index 5fd2345e9..8f838e820 100644 --- a/entc/integration/ent/file_delete.go +++ b/entc/integration/ent/file_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // FileDelete is the builder for deleting a File entity. type FileDelete struct { config + hooks []Hook + mutation *FileMutation predicates []predicate.File } @@ -30,7 +33,30 @@ func (fd *FileDelete) Where(ps ...predicate.File) *FileDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (fd *FileDelete) Exec(ctx context.Context) (int, error) { - return fd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(fd.hooks) == 0 { + affected, err = fd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fd.mutation = mutation + affected, err = fd.sqlExec(ctx) + return affected, err + }) + for i := len(fd.hooks); i > 0; i-- { + mut = fd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/file_update.go b/entc/integration/ent/file_update.go index 60d54491e..e7902abc2 100644 --- a/entc/integration/ent/file_update.go +++ b/entc/integration/ent/file_update.go @@ -8,7 +8,6 @@ package ent import ( "context" - "errors" "fmt" "strconv" @@ -24,18 +23,9 @@ import ( // FileUpdate is the builder for updating File entities. type FileUpdate struct { config - size *int - addsize *int - name *string - user *string - clearuser bool - group *string - cleargroup bool - owner map[string]struct{} - _type map[string]struct{} - clearedOwner bool - clearedType bool - predicates []predicate.File + hooks []Hook + mutation *FileMutation + predicates []predicate.File } // Where adds a new predicate for the builder. @@ -46,8 +36,8 @@ func (fu *FileUpdate) Where(ps ...predicate.File) *FileUpdate { // SetSize sets the size field. func (fu *FileUpdate) SetSize(i int) *FileUpdate { - fu.size = &i - fu.addsize = nil + fu.mutation.ResetSize() + fu.mutation.SetSize(i) return fu } @@ -61,23 +51,19 @@ func (fu *FileUpdate) SetNillableSize(i *int) *FileUpdate { // AddSize adds i to size. func (fu *FileUpdate) AddSize(i int) *FileUpdate { - if fu.addsize == nil { - fu.addsize = &i - } else { - *fu.addsize += i - } + fu.mutation.AddSize(i) return fu } // SetName sets the name field. func (fu *FileUpdate) SetName(s string) *FileUpdate { - fu.name = &s + fu.mutation.SetName(s) return fu } // SetUser sets the user field. func (fu *FileUpdate) SetUser(s string) *FileUpdate { - fu.user = &s + fu.mutation.SetUser(s) return fu } @@ -91,14 +77,13 @@ func (fu *FileUpdate) SetNillableUser(s *string) *FileUpdate { // ClearUser clears the value of user. func (fu *FileUpdate) ClearUser() *FileUpdate { - fu.user = nil - fu.clearuser = true + fu.mutation.ClearUser() return fu } // SetGroup sets the group field. func (fu *FileUpdate) SetGroup(s string) *FileUpdate { - fu.group = &s + fu.mutation.SetGroup(s) return fu } @@ -112,17 +97,13 @@ func (fu *FileUpdate) SetNillableGroup(s *string) *FileUpdate { // ClearGroup clears the value of group. func (fu *FileUpdate) ClearGroup() *FileUpdate { - fu.group = nil - fu.cleargroup = true + fu.mutation.ClearGroup() return fu } // SetOwnerID sets the owner edge to User by id. func (fu *FileUpdate) SetOwnerID(id string) *FileUpdate { - if fu.owner == nil { - fu.owner = make(map[string]struct{}) - } - fu.owner[id] = struct{}{} + fu.mutation.SetOwnerID(id) return fu } @@ -141,10 +122,7 @@ func (fu *FileUpdate) SetOwner(u *User) *FileUpdate { // SetTypeID sets the type edge to FileType by id. func (fu *FileUpdate) SetTypeID(id string) *FileUpdate { - if fu._type == nil { - fu._type = make(map[string]struct{}) - } - fu._type[id] = struct{}{} + fu.mutation.SetTypeID(id) return fu } @@ -163,30 +141,48 @@ func (fu *FileUpdate) SetType(f *FileType) *FileUpdate { // ClearOwner clears the owner edge to User. func (fu *FileUpdate) ClearOwner() *FileUpdate { - fu.clearedOwner = true + fu.mutation.ClearOwner() return fu } // ClearType clears the type edge to FileType. func (fu *FileUpdate) ClearType() *FileUpdate { - fu.clearedType = true + fu.mutation.ClearType() return fu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (fu *FileUpdate) Save(ctx context.Context) (int, error) { - if fu.size != nil { - if err := file.SizeValidator(*fu.size); err != nil { + if v, ok := fu.mutation.Size(); ok { + if err := file.SizeValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"size\": %v", err) } } - if len(fu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(fu.hooks) == 0 { + affected, err = fu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fu.mutation = mutation + affected, err = fu.sqlSave(ctx) + return affected, err + }) + for i := len(fu.hooks); i > 0; i-- { + mut = fu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fu.mutation); err != nil { + return 0, err + } } - if len(fu._type) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"type\"") - } - return fu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -229,54 +225,54 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := fu.size; value != nil { + if value, ok := fu.mutation.Size(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: file.FieldSize, }) } - if value := fu.addsize; value != nil { + if value, ok := fu.mutation.AddedSize(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: file.FieldSize, }) } - if value := fu.name; value != nil { + if value, ok := fu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldName, }) } - if value := fu.user; value != nil { + if value, ok := fu.mutation.User(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldUser, }) } - if fu.clearuser { + if fu.mutation.UserCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: file.FieldUser, }) } - if value := fu.group; value != nil { + if value, ok := fu.mutation.Group(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldGroup, }) } - if fu.cleargroup { + if fu.mutation.GroupCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: file.FieldGroup, }) } - if fu.clearedOwner { + if fu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -292,7 +288,7 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := fu.owner; len(nodes) > 0 { + if nodes := fu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -306,7 +302,7 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -315,7 +311,7 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if fu.clearedType { + if fu.mutation.TypeCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -331,7 +327,7 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := fu._type; len(nodes) > 0 { + if nodes := fu.mutation.TypeIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -345,7 +341,7 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -368,24 +364,14 @@ func (fu *FileUpdate) sqlSave(ctx context.Context) (n int, err error) { // FileUpdateOne is the builder for updating a single File entity. type FileUpdateOne struct { config - id string - size *int - addsize *int - name *string - user *string - clearuser bool - group *string - cleargroup bool - owner map[string]struct{} - _type map[string]struct{} - clearedOwner bool - clearedType bool + hooks []Hook + mutation *FileMutation } // SetSize sets the size field. func (fuo *FileUpdateOne) SetSize(i int) *FileUpdateOne { - fuo.size = &i - fuo.addsize = nil + fuo.mutation.ResetSize() + fuo.mutation.SetSize(i) return fuo } @@ -399,23 +385,19 @@ func (fuo *FileUpdateOne) SetNillableSize(i *int) *FileUpdateOne { // AddSize adds i to size. func (fuo *FileUpdateOne) AddSize(i int) *FileUpdateOne { - if fuo.addsize == nil { - fuo.addsize = &i - } else { - *fuo.addsize += i - } + fuo.mutation.AddSize(i) return fuo } // SetName sets the name field. func (fuo *FileUpdateOne) SetName(s string) *FileUpdateOne { - fuo.name = &s + fuo.mutation.SetName(s) return fuo } // SetUser sets the user field. func (fuo *FileUpdateOne) SetUser(s string) *FileUpdateOne { - fuo.user = &s + fuo.mutation.SetUser(s) return fuo } @@ -429,14 +411,13 @@ func (fuo *FileUpdateOne) SetNillableUser(s *string) *FileUpdateOne { // ClearUser clears the value of user. func (fuo *FileUpdateOne) ClearUser() *FileUpdateOne { - fuo.user = nil - fuo.clearuser = true + fuo.mutation.ClearUser() return fuo } // SetGroup sets the group field. func (fuo *FileUpdateOne) SetGroup(s string) *FileUpdateOne { - fuo.group = &s + fuo.mutation.SetGroup(s) return fuo } @@ -450,17 +431,13 @@ func (fuo *FileUpdateOne) SetNillableGroup(s *string) *FileUpdateOne { // ClearGroup clears the value of group. func (fuo *FileUpdateOne) ClearGroup() *FileUpdateOne { - fuo.group = nil - fuo.cleargroup = true + fuo.mutation.ClearGroup() return fuo } // SetOwnerID sets the owner edge to User by id. func (fuo *FileUpdateOne) SetOwnerID(id string) *FileUpdateOne { - if fuo.owner == nil { - fuo.owner = make(map[string]struct{}) - } - fuo.owner[id] = struct{}{} + fuo.mutation.SetOwnerID(id) return fuo } @@ -479,10 +456,7 @@ func (fuo *FileUpdateOne) SetOwner(u *User) *FileUpdateOne { // SetTypeID sets the type edge to FileType by id. func (fuo *FileUpdateOne) SetTypeID(id string) *FileUpdateOne { - if fuo._type == nil { - fuo._type = make(map[string]struct{}) - } - fuo._type[id] = struct{}{} + fuo.mutation.SetTypeID(id) return fuo } @@ -501,30 +475,48 @@ func (fuo *FileUpdateOne) SetType(f *FileType) *FileUpdateOne { // ClearOwner clears the owner edge to User. func (fuo *FileUpdateOne) ClearOwner() *FileUpdateOne { - fuo.clearedOwner = true + fuo.mutation.ClearOwner() return fuo } // ClearType clears the type edge to FileType. func (fuo *FileUpdateOne) ClearType() *FileUpdateOne { - fuo.clearedType = true + fuo.mutation.ClearType() return fuo } // Save executes the query and returns the updated entity. func (fuo *FileUpdateOne) Save(ctx context.Context) (*File, error) { - if fuo.size != nil { - if err := file.SizeValidator(*fuo.size); err != nil { + if v, ok := fuo.mutation.Size(); ok { + if err := file.SizeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"size\": %v", err) } } - if len(fuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *File + ) + if len(fuo.hooks) == 0 { + node, err = fuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fuo.mutation = mutation + node, err = fuo.sqlSave(ctx) + return node, err + }) + for i := len(fuo.hooks); i > 0; i-- { + mut = fuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fuo.mutation); err != nil { + return nil, err + } } - if len(fuo._type) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"type\"") - } - return fuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -555,60 +547,64 @@ func (fuo *FileUpdateOne) sqlSave(ctx context.Context) (f *File, err error) { Table: file.Table, Columns: file.Columns, ID: &sqlgraph.FieldSpec{ - Value: fuo.id, Type: field.TypeString, Column: file.FieldID, }, }, } - if value := fuo.size; value != nil { + id, ok := fuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing File.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := fuo.mutation.Size(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: file.FieldSize, }) } - if value := fuo.addsize; value != nil { + if value, ok := fuo.mutation.AddedSize(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: file.FieldSize, }) } - if value := fuo.name; value != nil { + if value, ok := fuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldName, }) } - if value := fuo.user; value != nil { + if value, ok := fuo.mutation.User(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldUser, }) } - if fuo.clearuser { + if fuo.mutation.UserCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: file.FieldUser, }) } - if value := fuo.group; value != nil { + if value, ok := fuo.mutation.Group(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: file.FieldGroup, }) } - if fuo.cleargroup { + if fuo.mutation.GroupCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: file.FieldGroup, }) } - if fuo.clearedOwner { + if fuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -624,7 +620,7 @@ func (fuo *FileUpdateOne) sqlSave(ctx context.Context) (f *File, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := fuo.owner; len(nodes) > 0 { + if nodes := fuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -638,7 +634,7 @@ func (fuo *FileUpdateOne) sqlSave(ctx context.Context) (f *File, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -647,7 +643,7 @@ func (fuo *FileUpdateOne) sqlSave(ctx context.Context) (f *File, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if fuo.clearedType { + if fuo.mutation.TypeCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -663,7 +659,7 @@ func (fuo *FileUpdateOne) sqlSave(ctx context.Context) (f *File, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := fuo._type; len(nodes) > 0 { + if nodes := fuo.mutation.TypeIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -677,7 +673,7 @@ func (fuo *FileUpdateOne) sqlSave(ctx context.Context) (f *File, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/filetype/filetype.go b/entc/integration/ent/filetype/filetype.go index 154d1548e..7961e4395 100644 --- a/entc/integration/ent/filetype/filetype.go +++ b/entc/integration/ent/filetype/filetype.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the filetype type in the database. Label = "file_type" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeFiles holds the string denoting the files edge name in mutations. + EdgeFiles = "files" + // Table holds the table name of the filetype in the database. Table = "file_types" // FilesTable is the table the holds the files relation/edge. diff --git a/entc/integration/ent/filetype_create.go b/entc/integration/ent/filetype_create.go index 41e3e8c22..4615c4922 100644 --- a/entc/integration/ent/filetype_create.go +++ b/entc/integration/ent/filetype_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,24 +21,19 @@ import ( // FileTypeCreate is the builder for creating a FileType entity. type FileTypeCreate struct { config - name *string - files map[string]struct{} + mutation *FileTypeMutation + hooks []Hook } // SetName sets the name field. func (ftc *FileTypeCreate) SetName(s string) *FileTypeCreate { - ftc.name = &s + ftc.mutation.SetName(s) return ftc } // AddFileIDs adds the files edge to File by ids. func (ftc *FileTypeCreate) AddFileIDs(ids ...string) *FileTypeCreate { - if ftc.files == nil { - ftc.files = make(map[string]struct{}) - } - for i := range ids { - ftc.files[ids[i]] = struct{}{} - } + ftc.mutation.AddFileIDs(ids...) return ftc } @@ -52,10 +48,33 @@ func (ftc *FileTypeCreate) AddFiles(f ...*File) *FileTypeCreate { // Save creates the FileType in the database. func (ftc *FileTypeCreate) Save(ctx context.Context) (*FileType, error) { - if ftc.name == nil { + if _, ok := ftc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return ftc.sqlSave(ctx) + var ( + err error + node *FileType + ) + if len(ftc.hooks) == 0 { + node, err = ftc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftc.mutation = mutation + node, err = ftc.sqlSave(ctx) + return node, err + }) + for i := len(ftc.hooks); i > 0; i-- { + mut = ftc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -78,15 +97,15 @@ func (ftc *FileTypeCreate) sqlSave(ctx context.Context) (*FileType, error) { }, } ) - if value := ftc.name; value != nil { + if value, ok := ftc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: filetype.FieldName, }) - ft.Name = *value + ft.Name = value } - if nodes := ftc.files; len(nodes) > 0 { + if nodes := ftc.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -100,7 +119,7 @@ func (ftc *FileTypeCreate) sqlSave(ctx context.Context) (*FileType, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/filetype_delete.go b/entc/integration/ent/filetype_delete.go index af54edfd5..c96264971 100644 --- a/entc/integration/ent/filetype_delete.go +++ b/entc/integration/ent/filetype_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // FileTypeDelete is the builder for deleting a FileType entity. type FileTypeDelete struct { config + hooks []Hook + mutation *FileTypeMutation predicates []predicate.FileType } @@ -30,7 +33,30 @@ func (ftd *FileTypeDelete) Where(ps ...predicate.FileType) *FileTypeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ftd *FileTypeDelete) Exec(ctx context.Context) (int, error) { - return ftd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ftd.hooks) == 0 { + affected, err = ftd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftd.mutation = mutation + affected, err = ftd.sqlExec(ctx) + return affected, err + }) + for i := len(ftd.hooks); i > 0; i-- { + mut = ftd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/filetype_update.go b/entc/integration/ent/filetype_update.go index 7fea7452e..cc9a95f08 100644 --- a/entc/integration/ent/filetype_update.go +++ b/entc/integration/ent/filetype_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql" @@ -21,10 +22,9 @@ import ( // FileTypeUpdate is the builder for updating FileType entities. type FileTypeUpdate struct { config - name *string - files map[string]struct{} - removedFiles map[string]struct{} - predicates []predicate.FileType + hooks []Hook + mutation *FileTypeMutation + predicates []predicate.FileType } // Where adds a new predicate for the builder. @@ -35,18 +35,13 @@ func (ftu *FileTypeUpdate) Where(ps ...predicate.FileType) *FileTypeUpdate { // SetName sets the name field. func (ftu *FileTypeUpdate) SetName(s string) *FileTypeUpdate { - ftu.name = &s + ftu.mutation.SetName(s) return ftu } // AddFileIDs adds the files edge to File by ids. func (ftu *FileTypeUpdate) AddFileIDs(ids ...string) *FileTypeUpdate { - if ftu.files == nil { - ftu.files = make(map[string]struct{}) - } - for i := range ids { - ftu.files[ids[i]] = struct{}{} - } + ftu.mutation.AddFileIDs(ids...) return ftu } @@ -61,12 +56,7 @@ func (ftu *FileTypeUpdate) AddFiles(f ...*File) *FileTypeUpdate { // RemoveFileIDs removes the files edge to File by ids. func (ftu *FileTypeUpdate) RemoveFileIDs(ids ...string) *FileTypeUpdate { - if ftu.removedFiles == nil { - ftu.removedFiles = make(map[string]struct{}) - } - for i := range ids { - ftu.removedFiles[ids[i]] = struct{}{} - } + ftu.mutation.RemoveFileIDs(ids...) return ftu } @@ -81,7 +71,31 @@ func (ftu *FileTypeUpdate) RemoveFiles(f ...*File) *FileTypeUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (ftu *FileTypeUpdate) Save(ctx context.Context) (int, error) { - return ftu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(ftu.hooks) == 0 { + affected, err = ftu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftu.mutation = mutation + affected, err = ftu.sqlSave(ctx) + return affected, err + }) + for i := len(ftu.hooks); i > 0; i-- { + mut = ftu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -124,14 +138,14 @@ func (ftu *FileTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := ftu.name; value != nil { + if value, ok := ftu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: filetype.FieldName, }) } - if nodes := ftu.removedFiles; len(nodes) > 0 { + if nodes := ftu.mutation.RemovedFilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -145,7 +159,7 @@ func (ftu *FileTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -154,7 +168,7 @@ func (ftu *FileTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := ftu.files; len(nodes) > 0 { + if nodes := ftu.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -168,7 +182,7 @@ func (ftu *FileTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -191,26 +205,19 @@ func (ftu *FileTypeUpdate) sqlSave(ctx context.Context) (n int, err error) { // FileTypeUpdateOne is the builder for updating a single FileType entity. type FileTypeUpdateOne struct { config - id string - name *string - files map[string]struct{} - removedFiles map[string]struct{} + hooks []Hook + mutation *FileTypeMutation } // SetName sets the name field. func (ftuo *FileTypeUpdateOne) SetName(s string) *FileTypeUpdateOne { - ftuo.name = &s + ftuo.mutation.SetName(s) return ftuo } // AddFileIDs adds the files edge to File by ids. func (ftuo *FileTypeUpdateOne) AddFileIDs(ids ...string) *FileTypeUpdateOne { - if ftuo.files == nil { - ftuo.files = make(map[string]struct{}) - } - for i := range ids { - ftuo.files[ids[i]] = struct{}{} - } + ftuo.mutation.AddFileIDs(ids...) return ftuo } @@ -225,12 +232,7 @@ func (ftuo *FileTypeUpdateOne) AddFiles(f ...*File) *FileTypeUpdateOne { // RemoveFileIDs removes the files edge to File by ids. func (ftuo *FileTypeUpdateOne) RemoveFileIDs(ids ...string) *FileTypeUpdateOne { - if ftuo.removedFiles == nil { - ftuo.removedFiles = make(map[string]struct{}) - } - for i := range ids { - ftuo.removedFiles[ids[i]] = struct{}{} - } + ftuo.mutation.RemoveFileIDs(ids...) return ftuo } @@ -245,7 +247,31 @@ func (ftuo *FileTypeUpdateOne) RemoveFiles(f ...*File) *FileTypeUpdateOne { // Save executes the query and returns the updated entity. func (ftuo *FileTypeUpdateOne) Save(ctx context.Context) (*FileType, error) { - return ftuo.sqlSave(ctx) + + var ( + err error + node *FileType + ) + if len(ftuo.hooks) == 0 { + node, err = ftuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftuo.mutation = mutation + node, err = ftuo.sqlSave(ctx) + return node, err + }) + for i := len(ftuo.hooks); i > 0; i-- { + mut = ftuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -276,20 +302,24 @@ func (ftuo *FileTypeUpdateOne) sqlSave(ctx context.Context) (ft *FileType, err e Table: filetype.Table, Columns: filetype.Columns, ID: &sqlgraph.FieldSpec{ - Value: ftuo.id, Type: field.TypeString, Column: filetype.FieldID, }, }, } - if value := ftuo.name; value != nil { + id, ok := ftuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing FileType.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := ftuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: filetype.FieldName, }) } - if nodes := ftuo.removedFiles; len(nodes) > 0 { + if nodes := ftuo.mutation.RemovedFilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -303,7 +333,7 @@ func (ftuo *FileTypeUpdateOne) sqlSave(ctx context.Context) (ft *FileType, err e }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -312,7 +342,7 @@ func (ftuo *FileTypeUpdateOne) sqlSave(ctx context.Context) (ft *FileType, err e } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := ftuo.files; len(nodes) > 0 { + if nodes := ftuo.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -326,7 +356,7 @@ func (ftuo *FileTypeUpdateOne) sqlSave(ctx context.Context) (ft *FileType, err e }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/group/group.go b/entc/integration/ent/group/group.go index ead86526c..84a6e175f 100644 --- a/entc/integration/ent/group/group.go +++ b/entc/integration/ent/group/group.go @@ -6,25 +6,25 @@ package group -import ( - "github.com/facebookincubator/ent/entc/integration/ent/schema" -) - const ( // Label holds the string label denoting the group type in the database. Label = "group" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldActive holds the string denoting the active vertex property in the database. - FieldActive = "active" - // FieldExpire holds the string denoting the expire vertex property in the database. - FieldExpire = "expire" - // FieldType holds the string denoting the type vertex property in the database. - FieldType = "type" - // FieldMaxUsers holds the string denoting the max_users vertex property in the database. - FieldMaxUsers = "max_users" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" + FieldID = "id" // FieldActive holds the string denoting the active vertex property in the database. + FieldActive = "active" // FieldExpire holds the string denoting the expire vertex property in the database. + FieldExpire = "expire" // FieldType holds the string denoting the type vertex property in the database. + FieldType = "type" // FieldMaxUsers holds the string denoting the max_users vertex property in the database. + FieldMaxUsers = "max_users" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" + + // EdgeFiles holds the string denoting the files edge name in mutations. + EdgeFiles = "files" + // EdgeBlocked holds the string denoting the blocked edge name in mutations. + EdgeBlocked = "blocked" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // EdgeInfo holds the string denoting the info edge name in mutations. + EdgeInfo = "info" // Table holds the table name of the group in the database. Table = "groups" @@ -78,55 +78,14 @@ var ( ) var ( - fields = schema.Group{}.Fields() - - // descActive is the schema descriptor for active field. - descActive = fields[0].Descriptor() // DefaultActive holds the default value on creation for the active field. - DefaultActive = descActive.Default.(bool) - - // descType is the schema descriptor for type field. - descType = fields[2].Descriptor() + DefaultActive bool // TypeValidator is a validator for the "type" field. It is called by the builders before save. - TypeValidator = func() func(string) error { - validators := descType.Validators - fns := [...]func(string) error{ - validators[0].(func(string) error), - validators[1].(func(string) error), - } - return func(_type string) error { - for _, fn := range fns { - if err := fn(_type); err != nil { - return err - } - } - return nil - } - }() - - // descMaxUsers is the schema descriptor for max_users field. - descMaxUsers = fields[3].Descriptor() + TypeValidator func(string) error // DefaultMaxUsers holds the default value on creation for the max_users field. - DefaultMaxUsers = descMaxUsers.Default.(int) + DefaultMaxUsers int // MaxUsersValidator is a validator for the "max_users" field. It is called by the builders before save. - MaxUsersValidator = descMaxUsers.Validators[0].(func(int) error) - - // descName is the schema descriptor for name field. - descName = fields[4].Descriptor() + MaxUsersValidator func(int) error // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator = func() func(string) error { - validators := descName.Validators - fns := [...]func(string) error{ - validators[0].(func(string) error), - validators[1].(func(string) error), - } - return func(name string) error { - for _, fn := range fns { - if err := fn(name); err != nil { - return err - } - } - return nil - } - }() + NameValidator func(string) error ) diff --git a/entc/integration/ent/group_create.go b/entc/integration/ent/group_create.go index f7de5ce1e..2511f17e0 100644 --- a/entc/integration/ent/group_create.go +++ b/entc/integration/ent/group_create.go @@ -24,20 +24,13 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - active *bool - expire *time.Time - _type *string - max_users *int - name *string - files map[string]struct{} - blocked map[string]struct{} - users map[string]struct{} - info map[string]struct{} + mutation *GroupMutation + hooks []Hook } // SetActive sets the active field. func (gc *GroupCreate) SetActive(b bool) *GroupCreate { - gc.active = &b + gc.mutation.SetActive(b) return gc } @@ -51,13 +44,13 @@ func (gc *GroupCreate) SetNillableActive(b *bool) *GroupCreate { // SetExpire sets the expire field. func (gc *GroupCreate) SetExpire(t time.Time) *GroupCreate { - gc.expire = &t + gc.mutation.SetExpire(t) return gc } // SetType sets the type field. func (gc *GroupCreate) SetType(s string) *GroupCreate { - gc._type = &s + gc.mutation.SetType(s) return gc } @@ -71,7 +64,7 @@ func (gc *GroupCreate) SetNillableType(s *string) *GroupCreate { // SetMaxUsers sets the max_users field. func (gc *GroupCreate) SetMaxUsers(i int) *GroupCreate { - gc.max_users = &i + gc.mutation.SetMaxUsers(i) return gc } @@ -85,18 +78,13 @@ func (gc *GroupCreate) SetNillableMaxUsers(i *int) *GroupCreate { // SetName sets the name field. func (gc *GroupCreate) SetName(s string) *GroupCreate { - gc.name = &s + gc.mutation.SetName(s) return gc } // AddFileIDs adds the files edge to File by ids. func (gc *GroupCreate) AddFileIDs(ids ...string) *GroupCreate { - if gc.files == nil { - gc.files = make(map[string]struct{}) - } - for i := range ids { - gc.files[ids[i]] = struct{}{} - } + gc.mutation.AddFileIDs(ids...) return gc } @@ -111,12 +99,7 @@ func (gc *GroupCreate) AddFiles(f ...*File) *GroupCreate { // AddBlockedIDs adds the blocked edge to User by ids. func (gc *GroupCreate) AddBlockedIDs(ids ...string) *GroupCreate { - if gc.blocked == nil { - gc.blocked = make(map[string]struct{}) - } - for i := range ids { - gc.blocked[ids[i]] = struct{}{} - } + gc.mutation.AddBlockedIDs(ids...) return gc } @@ -131,12 +114,7 @@ func (gc *GroupCreate) AddBlocked(u ...*User) *GroupCreate { // AddUserIDs adds the users edge to User by ids. func (gc *GroupCreate) AddUserIDs(ids ...string) *GroupCreate { - if gc.users == nil { - gc.users = make(map[string]struct{}) - } - for i := range ids { - gc.users[ids[i]] = struct{}{} - } + gc.mutation.AddUserIDs(ids...) return gc } @@ -151,10 +129,7 @@ func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { // SetInfoID sets the info edge to GroupInfo by id. func (gc *GroupCreate) SetInfoID(id string) *GroupCreate { - if gc.info == nil { - gc.info = make(map[string]struct{}) - } - gc.info[id] = struct{}{} + gc.mutation.SetInfoID(id) return gc } @@ -165,38 +140,62 @@ func (gc *GroupCreate) SetInfo(g *GroupInfo) *GroupCreate { // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - if gc.active == nil { + if _, ok := gc.mutation.Active(); !ok { v := group.DefaultActive - gc.active = &v + gc.mutation.SetActive(v) } - if gc.expire == nil { + if _, ok := gc.mutation.Expire(); !ok { return nil, errors.New("ent: missing required field \"expire\"") } - if gc._type != nil { - if err := group.TypeValidator(*gc._type); err != nil { + if v, ok := gc.mutation.GetType(); ok { + if err := group.TypeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"type\": %v", err) } } - if gc.max_users == nil { + if _, ok := gc.mutation.MaxUsers(); !ok { v := group.DefaultMaxUsers - gc.max_users = &v + gc.mutation.SetMaxUsers(v) } - if err := group.MaxUsersValidator(*gc.max_users); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) + if v, ok := gc.mutation.MaxUsers(); ok { + if err := group.MaxUsersValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) + } } - if gc.name == nil { + if _, ok := gc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if err := group.NameValidator(*gc.name); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + if v, ok := gc.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + } } - if len(gc.info) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"info\"") - } - if gc.info == nil { + if _, ok := gc.mutation.InfoID(); !ok { return nil, errors.New("ent: missing required edge \"info\"") } - return gc.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -219,47 +218,47 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, } ) - if value := gc.active; value != nil { + if value, ok := gc.mutation.Active(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeBool, - Value: *value, + Value: value, Column: group.FieldActive, }) - gr.Active = *value + gr.Active = value } - if value := gc.expire; value != nil { + if value, ok := gc.mutation.Expire(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: group.FieldExpire, }) - gr.Expire = *value + gr.Expire = value } - if value := gc._type; value != nil { + if value, ok := gc.mutation.GetType(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldType, }) - gr.Type = value + gr.Type = &value } - if value := gc.max_users; value != nil { + if value, ok := gc.mutation.MaxUsers(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) - gr.MaxUsers = *value + gr.MaxUsers = value } - if value := gc.name; value != nil { + if value, ok := gc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) - gr.Name = *value + gr.Name = value } - if nodes := gc.files; len(nodes) > 0 { + if nodes := gc.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -273,7 +272,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -282,7 +281,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := gc.blocked; len(nodes) > 0 { + if nodes := gc.mutation.BlockedIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -296,7 +295,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -305,7 +304,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := gc.users; len(nodes) > 0 { + if nodes := gc.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -319,7 +318,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -328,7 +327,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := gc.info; len(nodes) > 0 { + if nodes := gc.mutation.InfoIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -342,7 +341,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/group_delete.go b/entc/integration/ent/group_delete.go index e2016f5d8..89f7f4f18 100644 --- a/entc/integration/ent/group_delete.go +++ b/entc/integration/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/group_update.go b/entc/integration/ent/group_update.go index 5c6e34dfa..417f00abf 100644 --- a/entc/integration/ent/group_update.go +++ b/entc/integration/ent/group_update.go @@ -26,23 +26,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - active *bool - expire *time.Time - _type *string - clear_type bool - max_users *int - addmax_users *int - clearmax_users bool - name *string - files map[string]struct{} - blocked map[string]struct{} - users map[string]struct{} - info map[string]struct{} - removedFiles map[string]struct{} - removedBlocked map[string]struct{} - removedUsers map[string]struct{} - clearedInfo bool - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -53,7 +39,7 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // SetActive sets the active field. func (gu *GroupUpdate) SetActive(b bool) *GroupUpdate { - gu.active = &b + gu.mutation.SetActive(b) return gu } @@ -67,13 +53,13 @@ func (gu *GroupUpdate) SetNillableActive(b *bool) *GroupUpdate { // SetExpire sets the expire field. func (gu *GroupUpdate) SetExpire(t time.Time) *GroupUpdate { - gu.expire = &t + gu.mutation.SetExpire(t) return gu } // SetType sets the type field. func (gu *GroupUpdate) SetType(s string) *GroupUpdate { - gu._type = &s + gu.mutation.SetType(s) return gu } @@ -87,15 +73,14 @@ func (gu *GroupUpdate) SetNillableType(s *string) *GroupUpdate { // ClearType clears the value of type. func (gu *GroupUpdate) ClearType() *GroupUpdate { - gu._type = nil - gu.clear_type = true + gu.mutation.ClearType() return gu } // SetMaxUsers sets the max_users field. func (gu *GroupUpdate) SetMaxUsers(i int) *GroupUpdate { - gu.max_users = &i - gu.addmax_users = nil + gu.mutation.ResetMaxUsers() + gu.mutation.SetMaxUsers(i) return gu } @@ -109,35 +94,25 @@ func (gu *GroupUpdate) SetNillableMaxUsers(i *int) *GroupUpdate { // AddMaxUsers adds i to max_users. func (gu *GroupUpdate) AddMaxUsers(i int) *GroupUpdate { - if gu.addmax_users == nil { - gu.addmax_users = &i - } else { - *gu.addmax_users += i - } + gu.mutation.AddMaxUsers(i) return gu } // ClearMaxUsers clears the value of max_users. func (gu *GroupUpdate) ClearMaxUsers() *GroupUpdate { - gu.max_users = nil - gu.clearmax_users = true + gu.mutation.ClearMaxUsers() return gu } // SetName sets the name field. func (gu *GroupUpdate) SetName(s string) *GroupUpdate { - gu.name = &s + gu.mutation.SetName(s) return gu } // AddFileIDs adds the files edge to File by ids. func (gu *GroupUpdate) AddFileIDs(ids ...string) *GroupUpdate { - if gu.files == nil { - gu.files = make(map[string]struct{}) - } - for i := range ids { - gu.files[ids[i]] = struct{}{} - } + gu.mutation.AddFileIDs(ids...) return gu } @@ -152,12 +127,7 @@ func (gu *GroupUpdate) AddFiles(f ...*File) *GroupUpdate { // AddBlockedIDs adds the blocked edge to User by ids. func (gu *GroupUpdate) AddBlockedIDs(ids ...string) *GroupUpdate { - if gu.blocked == nil { - gu.blocked = make(map[string]struct{}) - } - for i := range ids { - gu.blocked[ids[i]] = struct{}{} - } + gu.mutation.AddBlockedIDs(ids...) return gu } @@ -172,12 +142,7 @@ func (gu *GroupUpdate) AddBlocked(u ...*User) *GroupUpdate { // AddUserIDs adds the users edge to User by ids. func (gu *GroupUpdate) AddUserIDs(ids ...string) *GroupUpdate { - if gu.users == nil { - gu.users = make(map[string]struct{}) - } - for i := range ids { - gu.users[ids[i]] = struct{}{} - } + gu.mutation.AddUserIDs(ids...) return gu } @@ -192,10 +157,7 @@ func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { // SetInfoID sets the info edge to GroupInfo by id. func (gu *GroupUpdate) SetInfoID(id string) *GroupUpdate { - if gu.info == nil { - gu.info = make(map[string]struct{}) - } - gu.info[id] = struct{}{} + gu.mutation.SetInfoID(id) return gu } @@ -206,12 +168,7 @@ func (gu *GroupUpdate) SetInfo(g *GroupInfo) *GroupUpdate { // RemoveFileIDs removes the files edge to File by ids. func (gu *GroupUpdate) RemoveFileIDs(ids ...string) *GroupUpdate { - if gu.removedFiles == nil { - gu.removedFiles = make(map[string]struct{}) - } - for i := range ids { - gu.removedFiles[ids[i]] = struct{}{} - } + gu.mutation.RemoveFileIDs(ids...) return gu } @@ -226,12 +183,7 @@ func (gu *GroupUpdate) RemoveFiles(f ...*File) *GroupUpdate { // RemoveBlockedIDs removes the blocked edge to User by ids. func (gu *GroupUpdate) RemoveBlockedIDs(ids ...string) *GroupUpdate { - if gu.removedBlocked == nil { - gu.removedBlocked = make(map[string]struct{}) - } - for i := range ids { - gu.removedBlocked[ids[i]] = struct{}{} - } + gu.mutation.RemoveBlockedIDs(ids...) return gu } @@ -246,12 +198,7 @@ func (gu *GroupUpdate) RemoveBlocked(u ...*User) *GroupUpdate { // RemoveUserIDs removes the users edge to User by ids. func (gu *GroupUpdate) RemoveUserIDs(ids ...string) *GroupUpdate { - if gu.removedUsers == nil { - gu.removedUsers = make(map[string]struct{}) - } - for i := range ids { - gu.removedUsers[ids[i]] = struct{}{} - } + gu.mutation.RemoveUserIDs(ids...) return gu } @@ -266,34 +213,55 @@ func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { // ClearInfo clears the info edge to GroupInfo. func (gu *GroupUpdate) ClearInfo() *GroupUpdate { - gu.clearedInfo = true + gu.mutation.ClearInfo() return gu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - if gu._type != nil { - if err := group.TypeValidator(*gu._type); err != nil { + if v, ok := gu.mutation.GetType(); ok { + if err := group.TypeValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"type\": %v", err) } } - if gu.max_users != nil { - if err := group.MaxUsersValidator(*gu.max_users); err != nil { + if v, ok := gu.mutation.MaxUsers(); ok { + if err := group.MaxUsersValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) } } - if gu.name != nil { - if err := group.NameValidator(*gu.name); err != nil { + if v, ok := gu.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(gu.info) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"info\"") - } - if gu.clearedInfo && gu.info == nil { + + if _, ok := gu.mutation.InfoID(); gu.mutation.InfoCleared() && !ok { return 0, errors.New("ent: clearing a unique edge \"info\"") } - return gu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -336,61 +304,61 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := gu.active; value != nil { + if value, ok := gu.mutation.Active(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBool, - Value: *value, + Value: value, Column: group.FieldActive, }) } - if value := gu.expire; value != nil { + if value, ok := gu.mutation.Expire(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: group.FieldExpire, }) } - if value := gu._type; value != nil { + if value, ok := gu.mutation.GetType(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldType, }) } - if gu.clear_type { + if gu.mutation.TypeCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: group.FieldType, }) } - if value := gu.max_users; value != nil { + if value, ok := gu.mutation.MaxUsers(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } - if value := gu.addmax_users; value != nil { + if value, ok := gu.mutation.AddedMaxUsers(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } - if gu.clearmax_users { + if gu.mutation.MaxUsersCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: group.FieldMaxUsers, }) } - if value := gu.name; value != nil { + if value, ok := gu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := gu.removedFiles; len(nodes) > 0 { + if nodes := gu.mutation.RemovedFilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -404,7 +372,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -413,7 +381,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.files; len(nodes) > 0 { + if nodes := gu.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -427,7 +395,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -436,7 +404,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := gu.removedBlocked; len(nodes) > 0 { + if nodes := gu.mutation.RemovedBlockedIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -450,7 +418,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -459,7 +427,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.blocked; len(nodes) > 0 { + if nodes := gu.mutation.BlockedIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -473,7 +441,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -482,7 +450,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := gu.removedUsers; len(nodes) > 0 { + if nodes := gu.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -496,7 +464,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -505,7 +473,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.users; len(nodes) > 0 { + if nodes := gu.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -519,7 +487,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -528,7 +496,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if gu.clearedInfo { + if gu.mutation.InfoCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -544,7 +512,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.info; len(nodes) > 0 { + if nodes := gu.mutation.InfoIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -558,7 +526,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -581,28 +549,13 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id string - active *bool - expire *time.Time - _type *string - clear_type bool - max_users *int - addmax_users *int - clearmax_users bool - name *string - files map[string]struct{} - blocked map[string]struct{} - users map[string]struct{} - info map[string]struct{} - removedFiles map[string]struct{} - removedBlocked map[string]struct{} - removedUsers map[string]struct{} - clearedInfo bool + hooks []Hook + mutation *GroupMutation } // SetActive sets the active field. func (guo *GroupUpdateOne) SetActive(b bool) *GroupUpdateOne { - guo.active = &b + guo.mutation.SetActive(b) return guo } @@ -616,13 +569,13 @@ func (guo *GroupUpdateOne) SetNillableActive(b *bool) *GroupUpdateOne { // SetExpire sets the expire field. func (guo *GroupUpdateOne) SetExpire(t time.Time) *GroupUpdateOne { - guo.expire = &t + guo.mutation.SetExpire(t) return guo } // SetType sets the type field. func (guo *GroupUpdateOne) SetType(s string) *GroupUpdateOne { - guo._type = &s + guo.mutation.SetType(s) return guo } @@ -636,15 +589,14 @@ func (guo *GroupUpdateOne) SetNillableType(s *string) *GroupUpdateOne { // ClearType clears the value of type. func (guo *GroupUpdateOne) ClearType() *GroupUpdateOne { - guo._type = nil - guo.clear_type = true + guo.mutation.ClearType() return guo } // SetMaxUsers sets the max_users field. func (guo *GroupUpdateOne) SetMaxUsers(i int) *GroupUpdateOne { - guo.max_users = &i - guo.addmax_users = nil + guo.mutation.ResetMaxUsers() + guo.mutation.SetMaxUsers(i) return guo } @@ -658,35 +610,25 @@ func (guo *GroupUpdateOne) SetNillableMaxUsers(i *int) *GroupUpdateOne { // AddMaxUsers adds i to max_users. func (guo *GroupUpdateOne) AddMaxUsers(i int) *GroupUpdateOne { - if guo.addmax_users == nil { - guo.addmax_users = &i - } else { - *guo.addmax_users += i - } + guo.mutation.AddMaxUsers(i) return guo } // ClearMaxUsers clears the value of max_users. func (guo *GroupUpdateOne) ClearMaxUsers() *GroupUpdateOne { - guo.max_users = nil - guo.clearmax_users = true + guo.mutation.ClearMaxUsers() return guo } // SetName sets the name field. func (guo *GroupUpdateOne) SetName(s string) *GroupUpdateOne { - guo.name = &s + guo.mutation.SetName(s) return guo } // AddFileIDs adds the files edge to File by ids. func (guo *GroupUpdateOne) AddFileIDs(ids ...string) *GroupUpdateOne { - if guo.files == nil { - guo.files = make(map[string]struct{}) - } - for i := range ids { - guo.files[ids[i]] = struct{}{} - } + guo.mutation.AddFileIDs(ids...) return guo } @@ -701,12 +643,7 @@ func (guo *GroupUpdateOne) AddFiles(f ...*File) *GroupUpdateOne { // AddBlockedIDs adds the blocked edge to User by ids. func (guo *GroupUpdateOne) AddBlockedIDs(ids ...string) *GroupUpdateOne { - if guo.blocked == nil { - guo.blocked = make(map[string]struct{}) - } - for i := range ids { - guo.blocked[ids[i]] = struct{}{} - } + guo.mutation.AddBlockedIDs(ids...) return guo } @@ -721,12 +658,7 @@ func (guo *GroupUpdateOne) AddBlocked(u ...*User) *GroupUpdateOne { // AddUserIDs adds the users edge to User by ids. func (guo *GroupUpdateOne) AddUserIDs(ids ...string) *GroupUpdateOne { - if guo.users == nil { - guo.users = make(map[string]struct{}) - } - for i := range ids { - guo.users[ids[i]] = struct{}{} - } + guo.mutation.AddUserIDs(ids...) return guo } @@ -741,10 +673,7 @@ func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { // SetInfoID sets the info edge to GroupInfo by id. func (guo *GroupUpdateOne) SetInfoID(id string) *GroupUpdateOne { - if guo.info == nil { - guo.info = make(map[string]struct{}) - } - guo.info[id] = struct{}{} + guo.mutation.SetInfoID(id) return guo } @@ -755,12 +684,7 @@ func (guo *GroupUpdateOne) SetInfo(g *GroupInfo) *GroupUpdateOne { // RemoveFileIDs removes the files edge to File by ids. func (guo *GroupUpdateOne) RemoveFileIDs(ids ...string) *GroupUpdateOne { - if guo.removedFiles == nil { - guo.removedFiles = make(map[string]struct{}) - } - for i := range ids { - guo.removedFiles[ids[i]] = struct{}{} - } + guo.mutation.RemoveFileIDs(ids...) return guo } @@ -775,12 +699,7 @@ func (guo *GroupUpdateOne) RemoveFiles(f ...*File) *GroupUpdateOne { // RemoveBlockedIDs removes the blocked edge to User by ids. func (guo *GroupUpdateOne) RemoveBlockedIDs(ids ...string) *GroupUpdateOne { - if guo.removedBlocked == nil { - guo.removedBlocked = make(map[string]struct{}) - } - for i := range ids { - guo.removedBlocked[ids[i]] = struct{}{} - } + guo.mutation.RemoveBlockedIDs(ids...) return guo } @@ -795,12 +714,7 @@ func (guo *GroupUpdateOne) RemoveBlocked(u ...*User) *GroupUpdateOne { // RemoveUserIDs removes the users edge to User by ids. func (guo *GroupUpdateOne) RemoveUserIDs(ids ...string) *GroupUpdateOne { - if guo.removedUsers == nil { - guo.removedUsers = make(map[string]struct{}) - } - for i := range ids { - guo.removedUsers[ids[i]] = struct{}{} - } + guo.mutation.RemoveUserIDs(ids...) return guo } @@ -815,34 +729,55 @@ func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { // ClearInfo clears the info edge to GroupInfo. func (guo *GroupUpdateOne) ClearInfo() *GroupUpdateOne { - guo.clearedInfo = true + guo.mutation.ClearInfo() return guo } // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - if guo._type != nil { - if err := group.TypeValidator(*guo._type); err != nil { + if v, ok := guo.mutation.GetType(); ok { + if err := group.TypeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"type\": %v", err) } } - if guo.max_users != nil { - if err := group.MaxUsersValidator(*guo.max_users); err != nil { + if v, ok := guo.mutation.MaxUsers(); ok { + if err := group.MaxUsersValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) } } - if guo.name != nil { - if err := group.NameValidator(*guo.name); err != nil { + if v, ok := guo.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(guo.info) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"info\"") - } - if guo.clearedInfo && guo.info == nil { + + if _, ok := guo.mutation.InfoID(); guo.mutation.InfoCleared() && !ok { return nil, errors.New("ent: clearing a unique edge \"info\"") } - return guo.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -873,67 +808,71 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeString, Column: group.FieldID, }, }, } - if value := guo.active; value != nil { + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := guo.mutation.Active(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBool, - Value: *value, + Value: value, Column: group.FieldActive, }) } - if value := guo.expire; value != nil { + if value, ok := guo.mutation.Expire(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: group.FieldExpire, }) } - if value := guo._type; value != nil { + if value, ok := guo.mutation.GetType(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldType, }) } - if guo.clear_type { + if guo.mutation.TypeCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: group.FieldType, }) } - if value := guo.max_users; value != nil { + if value, ok := guo.mutation.MaxUsers(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } - if value := guo.addmax_users; value != nil { + if value, ok := guo.mutation.AddedMaxUsers(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } - if guo.clearmax_users { + if guo.mutation.MaxUsersCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: group.FieldMaxUsers, }) } - if value := guo.name; value != nil { + if value, ok := guo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := guo.removedFiles; len(nodes) > 0 { + if nodes := guo.mutation.RemovedFilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -947,7 +886,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -956,7 +895,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.files; len(nodes) > 0 { + if nodes := guo.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -970,7 +909,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -979,7 +918,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := guo.removedBlocked; len(nodes) > 0 { + if nodes := guo.mutation.RemovedBlockedIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -993,7 +932,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -1002,7 +941,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.blocked; len(nodes) > 0 { + if nodes := guo.mutation.BlockedIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -1016,7 +955,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -1025,7 +964,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := guo.removedUsers; len(nodes) > 0 { + if nodes := guo.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -1039,7 +978,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -1048,7 +987,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.users; len(nodes) > 0 { + if nodes := guo.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -1062,7 +1001,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -1071,7 +1010,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if guo.clearedInfo { + if guo.mutation.InfoCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -1087,7 +1026,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.info; len(nodes) > 0 { + if nodes := guo.mutation.InfoIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -1101,7 +1040,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/groupinfo/groupinfo.go b/entc/integration/ent/groupinfo/groupinfo.go index 8dafe55b4..910ed6bee 100644 --- a/entc/integration/ent/groupinfo/groupinfo.go +++ b/entc/integration/ent/groupinfo/groupinfo.go @@ -6,20 +6,17 @@ package groupinfo -import ( - "github.com/facebookincubator/ent/entc/integration/ent/schema" -) - const ( // Label holds the string label denoting the groupinfo type in the database. Label = "group_info" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldDesc holds the string denoting the desc vertex property in the database. - FieldDesc = "desc" - // FieldMaxUsers holds the string denoting the max_users vertex property in the database. + FieldID = "id" // FieldDesc holds the string denoting the desc vertex property in the database. + FieldDesc = "desc" // FieldMaxUsers holds the string denoting the max_users vertex property in the database. FieldMaxUsers = "max_users" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // Table holds the table name of the groupinfo in the database. Table = "group_infos" // GroupsTable is the table the holds the groups relation/edge. @@ -39,10 +36,6 @@ var Columns = []string{ } var ( - fields = schema.GroupInfo{}.Fields() - - // descMaxUsers is the schema descriptor for max_users field. - descMaxUsers = fields[1].Descriptor() // DefaultMaxUsers holds the default value on creation for the max_users field. - DefaultMaxUsers = descMaxUsers.Default.(int) + DefaultMaxUsers int ) diff --git a/entc/integration/ent/groupinfo_create.go b/entc/integration/ent/groupinfo_create.go index 8ad68a586..c81babf2b 100644 --- a/entc/integration/ent/groupinfo_create.go +++ b/entc/integration/ent/groupinfo_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,20 +21,19 @@ import ( // GroupInfoCreate is the builder for creating a GroupInfo entity. type GroupInfoCreate struct { config - desc *string - max_users *int - groups map[string]struct{} + mutation *GroupInfoMutation + hooks []Hook } // SetDesc sets the desc field. func (gic *GroupInfoCreate) SetDesc(s string) *GroupInfoCreate { - gic.desc = &s + gic.mutation.SetDesc(s) return gic } // SetMaxUsers sets the max_users field. func (gic *GroupInfoCreate) SetMaxUsers(i int) *GroupInfoCreate { - gic.max_users = &i + gic.mutation.SetMaxUsers(i) return gic } @@ -47,12 +47,7 @@ func (gic *GroupInfoCreate) SetNillableMaxUsers(i *int) *GroupInfoCreate { // AddGroupIDs adds the groups edge to Group by ids. func (gic *GroupInfoCreate) AddGroupIDs(ids ...string) *GroupInfoCreate { - if gic.groups == nil { - gic.groups = make(map[string]struct{}) - } - for i := range ids { - gic.groups[ids[i]] = struct{}{} - } + gic.mutation.AddGroupIDs(ids...) return gic } @@ -67,14 +62,37 @@ func (gic *GroupInfoCreate) AddGroups(g ...*Group) *GroupInfoCreate { // Save creates the GroupInfo in the database. func (gic *GroupInfoCreate) Save(ctx context.Context) (*GroupInfo, error) { - if gic.desc == nil { + if _, ok := gic.mutation.Desc(); !ok { return nil, errors.New("ent: missing required field \"desc\"") } - if gic.max_users == nil { + if _, ok := gic.mutation.MaxUsers(); !ok { v := groupinfo.DefaultMaxUsers - gic.max_users = &v + gic.mutation.SetMaxUsers(v) } - return gic.sqlSave(ctx) + var ( + err error + node *GroupInfo + ) + if len(gic.hooks) == 0 { + node, err = gic.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gic.mutation = mutation + node, err = gic.sqlSave(ctx) + return node, err + }) + for i := len(gic.hooks); i > 0; i-- { + mut = gic.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gic.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -97,23 +115,23 @@ func (gic *GroupInfoCreate) sqlSave(ctx context.Context) (*GroupInfo, error) { }, } ) - if value := gic.desc; value != nil { + if value, ok := gic.mutation.Desc(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: groupinfo.FieldDesc, }) - gi.Desc = *value + gi.Desc = value } - if value := gic.max_users; value != nil { + if value, ok := gic.mutation.MaxUsers(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: groupinfo.FieldMaxUsers, }) - gi.MaxUsers = *value + gi.MaxUsers = value } - if nodes := gic.groups; len(nodes) > 0 { + if nodes := gic.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -127,7 +145,7 @@ func (gic *GroupInfoCreate) sqlSave(ctx context.Context) (*GroupInfo, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/groupinfo_delete.go b/entc/integration/ent/groupinfo_delete.go index 9ecfa7728..3260391ee 100644 --- a/entc/integration/ent/groupinfo_delete.go +++ b/entc/integration/ent/groupinfo_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupInfoDelete is the builder for deleting a GroupInfo entity. type GroupInfoDelete struct { config + hooks []Hook + mutation *GroupInfoMutation predicates []predicate.GroupInfo } @@ -30,7 +33,30 @@ func (gid *GroupInfoDelete) Where(ps ...predicate.GroupInfo) *GroupInfoDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gid *GroupInfoDelete) Exec(ctx context.Context) (int, error) { - return gid.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gid.hooks) == 0 { + affected, err = gid.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gid.mutation = mutation + affected, err = gid.sqlExec(ctx) + return affected, err + }) + for i := len(gid.hooks); i > 0; i-- { + mut = gid.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gid.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/groupinfo_update.go b/entc/integration/ent/groupinfo_update.go index 87b04c7d5..c4d61ce64 100644 --- a/entc/integration/ent/groupinfo_update.go +++ b/entc/integration/ent/groupinfo_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql" @@ -21,12 +22,9 @@ import ( // GroupInfoUpdate is the builder for updating GroupInfo entities. type GroupInfoUpdate struct { config - desc *string - max_users *int - addmax_users *int - groups map[string]struct{} - removedGroups map[string]struct{} - predicates []predicate.GroupInfo + hooks []Hook + mutation *GroupInfoMutation + predicates []predicate.GroupInfo } // Where adds a new predicate for the builder. @@ -37,14 +35,14 @@ func (giu *GroupInfoUpdate) Where(ps ...predicate.GroupInfo) *GroupInfoUpdate { // SetDesc sets the desc field. func (giu *GroupInfoUpdate) SetDesc(s string) *GroupInfoUpdate { - giu.desc = &s + giu.mutation.SetDesc(s) return giu } // SetMaxUsers sets the max_users field. func (giu *GroupInfoUpdate) SetMaxUsers(i int) *GroupInfoUpdate { - giu.max_users = &i - giu.addmax_users = nil + giu.mutation.ResetMaxUsers() + giu.mutation.SetMaxUsers(i) return giu } @@ -58,22 +56,13 @@ func (giu *GroupInfoUpdate) SetNillableMaxUsers(i *int) *GroupInfoUpdate { // AddMaxUsers adds i to max_users. func (giu *GroupInfoUpdate) AddMaxUsers(i int) *GroupInfoUpdate { - if giu.addmax_users == nil { - giu.addmax_users = &i - } else { - *giu.addmax_users += i - } + giu.mutation.AddMaxUsers(i) return giu } // AddGroupIDs adds the groups edge to Group by ids. func (giu *GroupInfoUpdate) AddGroupIDs(ids ...string) *GroupInfoUpdate { - if giu.groups == nil { - giu.groups = make(map[string]struct{}) - } - for i := range ids { - giu.groups[ids[i]] = struct{}{} - } + giu.mutation.AddGroupIDs(ids...) return giu } @@ -88,12 +77,7 @@ func (giu *GroupInfoUpdate) AddGroups(g ...*Group) *GroupInfoUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (giu *GroupInfoUpdate) RemoveGroupIDs(ids ...string) *GroupInfoUpdate { - if giu.removedGroups == nil { - giu.removedGroups = make(map[string]struct{}) - } - for i := range ids { - giu.removedGroups[ids[i]] = struct{}{} - } + giu.mutation.RemoveGroupIDs(ids...) return giu } @@ -108,7 +92,31 @@ func (giu *GroupInfoUpdate) RemoveGroups(g ...*Group) *GroupInfoUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (giu *GroupInfoUpdate) Save(ctx context.Context) (int, error) { - return giu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(giu.hooks) == 0 { + affected, err = giu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + giu.mutation = mutation + affected, err = giu.sqlSave(ctx) + return affected, err + }) + for i := len(giu.hooks); i > 0; i-- { + mut = giu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, giu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -151,28 +159,28 @@ func (giu *GroupInfoUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := giu.desc; value != nil { + if value, ok := giu.mutation.Desc(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: groupinfo.FieldDesc, }) } - if value := giu.max_users; value != nil { + if value, ok := giu.mutation.MaxUsers(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: groupinfo.FieldMaxUsers, }) } - if value := giu.addmax_users; value != nil { + if value, ok := giu.mutation.AddedMaxUsers(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: groupinfo.FieldMaxUsers, }) } - if nodes := giu.removedGroups; len(nodes) > 0 { + if nodes := giu.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -186,7 +194,7 @@ func (giu *GroupInfoUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -195,7 +203,7 @@ func (giu *GroupInfoUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := giu.groups; len(nodes) > 0 { + if nodes := giu.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -209,7 +217,7 @@ func (giu *GroupInfoUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -232,24 +240,20 @@ func (giu *GroupInfoUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupInfoUpdateOne is the builder for updating a single GroupInfo entity. type GroupInfoUpdateOne struct { config - id string - desc *string - max_users *int - addmax_users *int - groups map[string]struct{} - removedGroups map[string]struct{} + hooks []Hook + mutation *GroupInfoMutation } // SetDesc sets the desc field. func (giuo *GroupInfoUpdateOne) SetDesc(s string) *GroupInfoUpdateOne { - giuo.desc = &s + giuo.mutation.SetDesc(s) return giuo } // SetMaxUsers sets the max_users field. func (giuo *GroupInfoUpdateOne) SetMaxUsers(i int) *GroupInfoUpdateOne { - giuo.max_users = &i - giuo.addmax_users = nil + giuo.mutation.ResetMaxUsers() + giuo.mutation.SetMaxUsers(i) return giuo } @@ -263,22 +267,13 @@ func (giuo *GroupInfoUpdateOne) SetNillableMaxUsers(i *int) *GroupInfoUpdateOne // AddMaxUsers adds i to max_users. func (giuo *GroupInfoUpdateOne) AddMaxUsers(i int) *GroupInfoUpdateOne { - if giuo.addmax_users == nil { - giuo.addmax_users = &i - } else { - *giuo.addmax_users += i - } + giuo.mutation.AddMaxUsers(i) return giuo } // AddGroupIDs adds the groups edge to Group by ids. func (giuo *GroupInfoUpdateOne) AddGroupIDs(ids ...string) *GroupInfoUpdateOne { - if giuo.groups == nil { - giuo.groups = make(map[string]struct{}) - } - for i := range ids { - giuo.groups[ids[i]] = struct{}{} - } + giuo.mutation.AddGroupIDs(ids...) return giuo } @@ -293,12 +288,7 @@ func (giuo *GroupInfoUpdateOne) AddGroups(g ...*Group) *GroupInfoUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (giuo *GroupInfoUpdateOne) RemoveGroupIDs(ids ...string) *GroupInfoUpdateOne { - if giuo.removedGroups == nil { - giuo.removedGroups = make(map[string]struct{}) - } - for i := range ids { - giuo.removedGroups[ids[i]] = struct{}{} - } + giuo.mutation.RemoveGroupIDs(ids...) return giuo } @@ -313,7 +303,31 @@ func (giuo *GroupInfoUpdateOne) RemoveGroups(g ...*Group) *GroupInfoUpdateOne { // Save executes the query and returns the updated entity. func (giuo *GroupInfoUpdateOne) Save(ctx context.Context) (*GroupInfo, error) { - return giuo.sqlSave(ctx) + + var ( + err error + node *GroupInfo + ) + if len(giuo.hooks) == 0 { + node, err = giuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + giuo.mutation = mutation + node, err = giuo.sqlSave(ctx) + return node, err + }) + for i := len(giuo.hooks); i > 0; i-- { + mut = giuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, giuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -344,34 +358,38 @@ func (giuo *GroupInfoUpdateOne) sqlSave(ctx context.Context) (gi *GroupInfo, err Table: groupinfo.Table, Columns: groupinfo.Columns, ID: &sqlgraph.FieldSpec{ - Value: giuo.id, Type: field.TypeString, Column: groupinfo.FieldID, }, }, } - if value := giuo.desc; value != nil { + id, ok := giuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing GroupInfo.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := giuo.mutation.Desc(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: groupinfo.FieldDesc, }) } - if value := giuo.max_users; value != nil { + if value, ok := giuo.mutation.MaxUsers(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: groupinfo.FieldMaxUsers, }) } - if value := giuo.addmax_users; value != nil { + if value, ok := giuo.mutation.AddedMaxUsers(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: groupinfo.FieldMaxUsers, }) } - if nodes := giuo.removedGroups; len(nodes) > 0 { + if nodes := giuo.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -385,7 +403,7 @@ func (giuo *GroupInfoUpdateOne) sqlSave(ctx context.Context) (gi *GroupInfo, err }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -394,7 +412,7 @@ func (giuo *GroupInfoUpdateOne) sqlSave(ctx context.Context) (gi *GroupInfo, err } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := giuo.groups; len(nodes) > 0 { + if nodes := giuo.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -408,7 +426,7 @@ func (giuo *GroupInfoUpdateOne) sqlSave(ctx context.Context) (gi *GroupInfo, err }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/hook/hook.go b/entc/integration/ent/hook/hook.go new file mode 100644 index 000000000..495881c29 --- /dev/null +++ b/entc/integration/ent/hook/hook.go @@ -0,0 +1,204 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" +) + +// The CardFunc type is an adapter to allow the use of ordinary +// function as Card mutator. +type CardFunc func(context.Context, *ent.CardMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CardFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CardMutation", m) + } + return f(ctx, mv) +} + +// The CommentFunc type is an adapter to allow the use of ordinary +// function as Comment mutator. +type CommentFunc func(context.Context, *ent.CommentMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CommentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CommentMutation", m) + } + return f(ctx, mv) +} + +// The FieldTypeFunc type is an adapter to allow the use of ordinary +// function as FieldType mutator. +type FieldTypeFunc func(context.Context, *ent.FieldTypeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f FieldTypeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FieldTypeMutation", m) + } + return f(ctx, mv) +} + +// The FileFunc type is an adapter to allow the use of ordinary +// function as File mutator. +type FileFunc func(context.Context, *ent.FileMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f FileFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FileMutation", m) + } + return f(ctx, mv) +} + +// The FileTypeFunc type is an adapter to allow the use of ordinary +// function as FileType mutator. +type FileTypeFunc func(context.Context, *ent.FileTypeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f FileTypeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FileTypeMutation", m) + } + return f(ctx, mv) +} + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The GroupInfoFunc type is an adapter to allow the use of ordinary +// function as GroupInfo mutator. +type GroupInfoFunc func(context.Context, *ent.GroupInfoMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupInfoFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupInfoMutation", m) + } + return f(ctx, mv) +} + +// The ItemFunc type is an adapter to allow the use of ordinary +// function as Item mutator. +type ItemFunc func(context.Context, *ent.ItemMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f ItemFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ItemMutation", m) + } + return f(ctx, mv) +} + +// The NodeFunc type is an adapter to allow the use of ordinary +// function as Node mutator. +type NodeFunc func(context.Context, *ent.NodeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f NodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.NodeMutation", m) + } + return f(ctx, mv) +} + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The SpecFunc type is an adapter to allow the use of ordinary +// function as Spec mutator. +type SpecFunc func(context.Context, *ent.SpecMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f SpecFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SpecMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/ent/item_create.go b/entc/integration/ent/item_create.go index ee52b29f3..0f92a1d0c 100644 --- a/entc/integration/ent/item_create.go +++ b/entc/integration/ent/item_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -18,11 +19,36 @@ import ( // ItemCreate is the builder for creating a Item entity. type ItemCreate struct { config + mutation *ItemMutation + hooks []Hook } // Save creates the Item in the database. func (ic *ItemCreate) Save(ctx context.Context) (*Item, error) { - return ic.sqlSave(ctx) + var ( + err error + node *Item + ) + if len(ic.hooks) == 0 { + node, err = ic.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ic.mutation = mutation + node, err = ic.sqlSave(ctx) + return node, err + }) + for i := len(ic.hooks); i > 0; i-- { + mut = ic.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ic.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. diff --git a/entc/integration/ent/item_delete.go b/entc/integration/ent/item_delete.go index 30a618b42..177a2ac4b 100644 --- a/entc/integration/ent/item_delete.go +++ b/entc/integration/ent/item_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // ItemDelete is the builder for deleting a Item entity. type ItemDelete struct { config + hooks []Hook + mutation *ItemMutation predicates []predicate.Item } @@ -30,7 +33,30 @@ func (id *ItemDelete) Where(ps ...predicate.Item) *ItemDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (id *ItemDelete) Exec(ctx context.Context) (int, error) { - return id.sqlExec(ctx) + var ( + err error + affected int + ) + if len(id.hooks) == 0 { + affected, err = id.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + id.mutation = mutation + affected, err = id.sqlExec(ctx) + return affected, err + }) + for i := len(id.hooks); i > 0; i-- { + mut = id.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, id.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/item_update.go b/entc/integration/ent/item_update.go index e2231a93e..00ae05d2e 100644 --- a/entc/integration/ent/item_update.go +++ b/entc/integration/ent/item_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // ItemUpdate is the builder for updating Item entities. type ItemUpdate struct { config + hooks []Hook + mutation *ItemMutation predicates []predicate.Item } @@ -30,7 +33,30 @@ func (iu *ItemUpdate) Where(ps ...predicate.Item) *ItemUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (iu *ItemUpdate) Save(ctx context.Context) (int, error) { - return iu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(iu.hooks) == 0 { + affected, err = iu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + iu.mutation = mutation + affected, err = iu.sqlSave(ctx) + return affected, err + }) + for i := len(iu.hooks); i > 0; i-- { + mut = iu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, iu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -87,12 +113,36 @@ func (iu *ItemUpdate) sqlSave(ctx context.Context) (n int, err error) { // ItemUpdateOne is the builder for updating a single Item entity. type ItemUpdateOne struct { config - id string + hooks []Hook + mutation *ItemMutation } // Save executes the query and returns the updated entity. func (iuo *ItemUpdateOne) Save(ctx context.Context) (*Item, error) { - return iuo.sqlSave(ctx) + var ( + err error + node *Item + ) + if len(iuo.hooks) == 0 { + node, err = iuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + iuo.mutation = mutation + node, err = iuo.sqlSave(ctx) + return node, err + }) + for i := len(iuo.hooks); i > 0; i-- { + mut = iuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, iuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -123,12 +173,16 @@ func (iuo *ItemUpdateOne) sqlSave(ctx context.Context) (i *Item, err error) { Table: item.Table, Columns: item.Columns, ID: &sqlgraph.FieldSpec{ - Value: iuo.id, Type: field.TypeString, Column: item.FieldID, }, }, } + id, ok := iuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Item.ID for update") + } + _spec.Node.ID.Value = id i = &Item{config: iuo.config} _spec.Assign = i.assignValues _spec.ScanValues = i.scanValues() diff --git a/entc/integration/ent/migrate/schema.go b/entc/integration/ent/migrate/schema.go index 1e92b74b5..1ba2c1b84 100644 --- a/entc/integration/ent/migrate/schema.go +++ b/entc/integration/ent/migrate/schema.go @@ -7,11 +7,6 @@ package migrate import ( - "github.com/facebookincubator/ent/entc/integration/ent/file" - "github.com/facebookincubator/ent/entc/integration/ent/group" - "github.com/facebookincubator/ent/entc/integration/ent/groupinfo" - "github.com/facebookincubator/ent/entc/integration/ent/user" - "github.com/facebookincubator/ent/dialect/sql/schema" "github.com/facebookincubator/ent/schema/field" ) @@ -93,7 +88,7 @@ var ( // FilesColumns holds the columns for the "files" table. FilesColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "fsize", Type: field.TypeInt, Default: file.DefaultSize}, + {Name: "fsize", Type: field.TypeInt, Default: 2147483647}, {Name: "name", Type: field.TypeString}, {Name: "user", Type: field.TypeString, Nullable: true}, {Name: "group", Type: field.TypeString, Nullable: true}, @@ -172,10 +167,10 @@ var ( // GroupsColumns holds the columns for the "groups" table. GroupsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "active", Type: field.TypeBool, Default: group.DefaultActive}, + {Name: "active", Type: field.TypeBool, Default: true}, {Name: "expire", Type: field.TypeTime}, {Name: "type", Type: field.TypeString, Nullable: true, Size: 255}, - {Name: "max_users", Type: field.TypeInt, Nullable: true, Default: group.DefaultMaxUsers}, + {Name: "max_users", Type: field.TypeInt, Nullable: true, Default: 10}, {Name: "name", Type: field.TypeString}, {Name: "group_info", Type: field.TypeInt, Nullable: true}, } @@ -198,7 +193,7 @@ var ( GroupInfosColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "desc", Type: field.TypeString}, - {Name: "max_users", Type: field.TypeInt, Default: groupinfo.DefaultMaxUsers}, + {Name: "max_users", Type: field.TypeInt, Default: 10000}, } // GroupInfosTable holds the schema information for the "group_infos" table. GroupInfosTable = &schema.Table{ @@ -292,11 +287,11 @@ var ( {Name: "optional_int", Type: field.TypeInt, Nullable: true}, {Name: "age", Type: field.TypeInt}, {Name: "name", Type: field.TypeString}, - {Name: "last", Type: field.TypeString, Default: user.DefaultLast}, + {Name: "last", Type: field.TypeString, Default: "unknown"}, {Name: "nickname", Type: field.TypeString, Unique: true, Nullable: true}, {Name: "phone", Type: field.TypeString, Unique: true, Nullable: true}, {Name: "password", Type: field.TypeString, Nullable: true}, - {Name: "role", Type: field.TypeEnum, Enums: []string{"user", "admin"}, Default: user.DefaultRole}, + {Name: "role", Type: field.TypeEnum, Enums: []string{"user", "admin"}, Default: "user"}, {Name: "group_blocked", Type: field.TypeInt, Nullable: true}, {Name: "user_spouse", Type: field.TypeInt, Unique: true, Nullable: true}, {Name: "user_parent", Type: field.TypeInt, Nullable: true}, diff --git a/entc/integration/ent/mutation.go b/entc/integration/ent/mutation.go new file mode 100644 index 000000000..78ae7a146 --- /dev/null +++ b/entc/integration/ent/mutation.go @@ -0,0 +1,7539 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "time" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/entc/integration/ent/card" + "github.com/facebookincubator/ent/entc/integration/ent/comment" + "github.com/facebookincubator/ent/entc/integration/ent/fieldtype" + "github.com/facebookincubator/ent/entc/integration/ent/file" + "github.com/facebookincubator/ent/entc/integration/ent/filetype" + "github.com/facebookincubator/ent/entc/integration/ent/group" + "github.com/facebookincubator/ent/entc/integration/ent/groupinfo" + "github.com/facebookincubator/ent/entc/integration/ent/node" + "github.com/facebookincubator/ent/entc/integration/ent/pet" + "github.com/facebookincubator/ent/entc/integration/ent/spec" + "github.com/facebookincubator/ent/entc/integration/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCard = "Card" + TypeComment = "Comment" + TypeFieldType = "FieldType" + TypeFile = "File" + TypeFileType = "FileType" + TypeGroup = "Group" + TypeGroupInfo = "GroupInfo" + TypeItem = "Item" + TypeNode = "Node" + TypePet = "Pet" + TypeSpec = "Spec" + TypeUser = "User" +) + +// CardMutation represents an operation that mutate the Cards +// nodes in the graph. +type CardMutation struct { + config + op Op + typ string + id *string + create_time *time.Time + update_time *time.Time + number *string + name *string + clearedFields map[string]bool + owner *string + clearedowner bool + spec map[string]struct{} + removedspec map[string]struct{} +} + +var _ ent.Mutation = (*CardMutation)(nil) + +// newCardMutation creates new mutation for $n.Name. +func newCardMutation(c config, op Op) *CardMutation { + return &CardMutation{ + config: c, + op: op, + typ: TypeCard, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CardMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CardMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CardMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetCreateTime sets the create_time field. +func (m *CardMutation) SetCreateTime(t time.Time) { + m.create_time = &t +} + +// CreateTime returns the create_time value in the mutation. +func (m *CardMutation) CreateTime() (r time.Time, exists bool) { + v := m.create_time + if v == nil { + return + } + return *v, true +} + +// ResetCreateTime reset all changes of the create_time field. +func (m *CardMutation) ResetCreateTime() { + m.create_time = nil +} + +// SetUpdateTime sets the update_time field. +func (m *CardMutation) SetUpdateTime(t time.Time) { + m.update_time = &t +} + +// UpdateTime returns the update_time value in the mutation. +func (m *CardMutation) UpdateTime() (r time.Time, exists bool) { + v := m.update_time + if v == nil { + return + } + return *v, true +} + +// ResetUpdateTime reset all changes of the update_time field. +func (m *CardMutation) ResetUpdateTime() { + m.update_time = nil +} + +// SetNumber sets the number field. +func (m *CardMutation) SetNumber(s string) { + m.number = &s +} + +// Number returns the number value in the mutation. +func (m *CardMutation) Number() (r string, exists bool) { + v := m.number + if v == nil { + return + } + return *v, true +} + +// ResetNumber reset all changes of the number field. +func (m *CardMutation) ResetNumber() { + m.number = nil +} + +// SetName sets the name field. +func (m *CardMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *CardMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ClearName clears the value of name. +func (m *CardMutation) ClearName() { + m.name = nil + m.clearedFields[card.FieldName] = true +} + +// NameCleared returns if the field name was cleared in this mutation. +func (m *CardMutation) NameCleared() bool { + return m.clearedFields[card.FieldName] +} + +// ResetName reset all changes of the name field. +func (m *CardMutation) ResetName() { + m.name = nil + delete(m.clearedFields, card.FieldName) +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CardMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CardMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CardMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CardMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CardMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CardMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// AddSpecIDs adds the spec edge to Spec by ids. +func (m *CardMutation) AddSpecIDs(ids ...string) { + if m.spec == nil { + m.spec = make(map[string]struct{}) + } + for i := range ids { + m.spec[ids[i]] = struct{}{} + } +} + +// RemoveSpecIDs removes the spec edge to Spec by ids. +func (m *CardMutation) RemoveSpecIDs(ids ...string) { + if m.removedspec == nil { + m.removedspec = make(map[string]struct{}) + } + for i := range ids { + m.removedspec[ids[i]] = struct{}{} + } +} + +// RemovedSpec returns the removed ids of spec. +func (m *CardMutation) RemovedSpecIDs() (ids []string) { + for id := range m.removedspec { + ids = append(ids, id) + } + return +} + +// SpecIDs returns the spec ids in the mutation. +func (m *CardMutation) SpecIDs() (ids []string) { + for id := range m.spec { + ids = append(ids, id) + } + return +} + +// ResetSpec reset all changes of the spec edge. +func (m *CardMutation) ResetSpec() { + m.spec = nil + m.removedspec = nil +} + +// Op returns the operation name. +func (m *CardMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Card). +func (m *CardMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CardMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.create_time != nil { + fields = append(fields, card.FieldCreateTime) + } + if m.update_time != nil { + fields = append(fields, card.FieldUpdateTime) + } + if m.number != nil { + fields = append(fields, card.FieldNumber) + } + if m.name != nil { + fields = append(fields, card.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CardMutation) Field(name string) (ent.Value, bool) { + switch name { + case card.FieldCreateTime: + return m.CreateTime() + case card.FieldUpdateTime: + return m.UpdateTime() + case card.FieldNumber: + return m.Number() + case card.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) SetField(name string, value ent.Value) error { + switch name { + case card.FieldCreateTime: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreateTime(v) + return nil + case card.FieldUpdateTime: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdateTime(v) + return nil + case card.FieldNumber: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNumber(v) + return nil + case card.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CardMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CardMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Card numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CardMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[card.FieldName] { + fields = append(fields, card.FieldName) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CardMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CardMutation) ClearField(name string) error { + switch name { + case card.FieldName: + m.ClearName() + return nil + } + return fmt.Errorf("unknown Card nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CardMutation) ResetField(name string) error { + switch name { + case card.FieldCreateTime: + m.ResetCreateTime() + return nil + case card.FieldUpdateTime: + m.ResetUpdateTime() + return nil + case card.FieldNumber: + m.ResetNumber() + return nil + case card.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CardMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.owner != nil { + edges = append(edges, card.EdgeOwner) + } + if m.spec != nil { + edges = append(edges, card.EdgeSpec) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CardMutation) AddedIDs(name string) []ent.Value { + switch name { + case card.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + case card.EdgeSpec: + ids := make([]ent.Value, 0, len(m.spec)) + for id := range m.spec { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CardMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedspec != nil { + edges = append(edges, card.EdgeSpec) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CardMutation) RemovedIDs(name string) []ent.Value { + switch name { + case card.EdgeSpec: + ids := make([]ent.Value, 0, len(m.removedspec)) + for id := range m.removedspec { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CardMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedowner { + edges = append(edges, card.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CardMutation) EdgeCleared(name string) bool { + switch name { + case card.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CardMutation) ClearEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Card unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CardMutation) ResetEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ResetOwner() + return nil + case card.EdgeSpec: + m.ResetSpec() + return nil + } + return fmt.Errorf("unknown Card edge %s", name) +} + +// CommentMutation represents an operation that mutate the Comments +// nodes in the graph. +type CommentMutation struct { + config + op Op + typ string + id *string + unique_int *int + addunique_int *int + unique_float *float64 + addunique_float *float64 + nillable_int *int + addnillable_int *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*CommentMutation)(nil) + +// newCommentMutation creates new mutation for $n.Name. +func newCommentMutation(c config, op Op) *CommentMutation { + return &CommentMutation{ + config: c, + op: op, + typ: TypeComment, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CommentMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CommentMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CommentMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetUniqueInt sets the unique_int field. +func (m *CommentMutation) SetUniqueInt(i int) { + m.unique_int = &i + m.addunique_int = nil +} + +// UniqueInt returns the unique_int value in the mutation. +func (m *CommentMutation) UniqueInt() (r int, exists bool) { + v := m.unique_int + if v == nil { + return + } + return *v, true +} + +// AddUniqueInt adds i to unique_int. +func (m *CommentMutation) AddUniqueInt(i int) { + if m.addunique_int != nil { + *m.addunique_int += i + } else { + m.addunique_int = &i + } +} + +// AddedUniqueInt returns the value that was added to the unique_int field in this mutation. +func (m *CommentMutation) AddedUniqueInt() (r int, exists bool) { + v := m.addunique_int + if v == nil { + return + } + return *v, true +} + +// ResetUniqueInt reset all changes of the unique_int field. +func (m *CommentMutation) ResetUniqueInt() { + m.unique_int = nil + m.addunique_int = nil +} + +// SetUniqueFloat sets the unique_float field. +func (m *CommentMutation) SetUniqueFloat(f float64) { + m.unique_float = &f + m.addunique_float = nil +} + +// UniqueFloat returns the unique_float value in the mutation. +func (m *CommentMutation) UniqueFloat() (r float64, exists bool) { + v := m.unique_float + if v == nil { + return + } + return *v, true +} + +// AddUniqueFloat adds f to unique_float. +func (m *CommentMutation) AddUniqueFloat(f float64) { + if m.addunique_float != nil { + *m.addunique_float += f + } else { + m.addunique_float = &f + } +} + +// AddedUniqueFloat returns the value that was added to the unique_float field in this mutation. +func (m *CommentMutation) AddedUniqueFloat() (r float64, exists bool) { + v := m.addunique_float + if v == nil { + return + } + return *v, true +} + +// ResetUniqueFloat reset all changes of the unique_float field. +func (m *CommentMutation) ResetUniqueFloat() { + m.unique_float = nil + m.addunique_float = nil +} + +// SetNillableInt sets the nillable_int field. +func (m *CommentMutation) SetNillableInt(i int) { + m.nillable_int = &i + m.addnillable_int = nil +} + +// NillableInt returns the nillable_int value in the mutation. +func (m *CommentMutation) NillableInt() (r int, exists bool) { + v := m.nillable_int + if v == nil { + return + } + return *v, true +} + +// AddNillableInt adds i to nillable_int. +func (m *CommentMutation) AddNillableInt(i int) { + if m.addnillable_int != nil { + *m.addnillable_int += i + } else { + m.addnillable_int = &i + } +} + +// AddedNillableInt returns the value that was added to the nillable_int field in this mutation. +func (m *CommentMutation) AddedNillableInt() (r int, exists bool) { + v := m.addnillable_int + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt clears the value of nillable_int. +func (m *CommentMutation) ClearNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + m.clearedFields[comment.FieldNillableInt] = true +} + +// NillableIntCleared returns if the field nillable_int was cleared in this mutation. +func (m *CommentMutation) NillableIntCleared() bool { + return m.clearedFields[comment.FieldNillableInt] +} + +// ResetNillableInt reset all changes of the nillable_int field. +func (m *CommentMutation) ResetNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + delete(m.clearedFields, comment.FieldNillableInt) +} + +// Op returns the operation name. +func (m *CommentMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Comment). +func (m *CommentMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CommentMutation) Fields() []string { + fields := make([]string, 0, 3) + if m.unique_int != nil { + fields = append(fields, comment.FieldUniqueInt) + } + if m.unique_float != nil { + fields = append(fields, comment.FieldUniqueFloat) + } + if m.nillable_int != nil { + fields = append(fields, comment.FieldNillableInt) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CommentMutation) Field(name string) (ent.Value, bool) { + switch name { + case comment.FieldUniqueInt: + return m.UniqueInt() + case comment.FieldUniqueFloat: + return m.UniqueFloat() + case comment.FieldNillableInt: + return m.NillableInt() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CommentMutation) SetField(name string, value ent.Value) error { + switch name { + case comment.FieldUniqueInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUniqueInt(v) + return nil + case comment.FieldUniqueFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUniqueFloat(v) + return nil + case comment.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt(v) + return nil + } + return fmt.Errorf("unknown Comment field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CommentMutation) AddedFields() []string { + var fields []string + if m.addunique_int != nil { + fields = append(fields, comment.FieldUniqueInt) + } + if m.addunique_float != nil { + fields = append(fields, comment.FieldUniqueFloat) + } + if m.addnillable_int != nil { + fields = append(fields, comment.FieldNillableInt) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CommentMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case comment.FieldUniqueInt: + return m.AddedUniqueInt() + case comment.FieldUniqueFloat: + return m.AddedUniqueFloat() + case comment.FieldNillableInt: + return m.AddedNillableInt() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CommentMutation) AddField(name string, value ent.Value) error { + switch name { + case comment.FieldUniqueInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUniqueInt(v) + return nil + case comment.FieldUniqueFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUniqueFloat(v) + return nil + case comment.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt(v) + return nil + } + return fmt.Errorf("unknown Comment numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CommentMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[comment.FieldNillableInt] { + fields = append(fields, comment.FieldNillableInt) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CommentMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CommentMutation) ClearField(name string) error { + switch name { + case comment.FieldNillableInt: + m.ClearNillableInt() + return nil + } + return fmt.Errorf("unknown Comment nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CommentMutation) ResetField(name string) error { + switch name { + case comment.FieldUniqueInt: + m.ResetUniqueInt() + return nil + case comment.FieldUniqueFloat: + m.ResetUniqueFloat() + return nil + case comment.FieldNillableInt: + m.ResetNillableInt() + return nil + } + return fmt.Errorf("unknown Comment field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CommentMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CommentMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CommentMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CommentMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CommentMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CommentMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CommentMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Comment unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CommentMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Comment edge %s", name) +} + +// FieldTypeMutation represents an operation that mutate the FieldTypes +// nodes in the graph. +type FieldTypeMutation struct { + config + op Op + typ string + id *string + int *int + addint *int + int8 *int8 + addint8 *int8 + int16 *int16 + addint16 *int16 + int32 *int32 + addint32 *int32 + int64 *int64 + addint64 *int64 + optional_int *int + addoptional_int *int + optional_int8 *int8 + addoptional_int8 *int8 + optional_int16 *int16 + addoptional_int16 *int16 + optional_int32 *int32 + addoptional_int32 *int32 + optional_int64 *int64 + addoptional_int64 *int64 + nillable_int *int + addnillable_int *int + nillable_int8 *int8 + addnillable_int8 *int8 + nillable_int16 *int16 + addnillable_int16 *int16 + nillable_int32 *int32 + addnillable_int32 *int32 + nillable_int64 *int64 + addnillable_int64 *int64 + validate_optional_int32 *int32 + addvalidate_optional_int32 *int32 + optional_uint *uint + addoptional_uint *uint + optional_uint8 *uint8 + addoptional_uint8 *uint8 + optional_uint16 *uint16 + addoptional_uint16 *uint16 + optional_uint32 *uint32 + addoptional_uint32 *uint32 + optional_uint64 *uint64 + addoptional_uint64 *uint64 + state *fieldtype.State + optional_float *float64 + addoptional_float *float64 + optional_float32 *float32 + addoptional_float32 *float32 + clearedFields map[string]bool +} + +var _ ent.Mutation = (*FieldTypeMutation)(nil) + +// newFieldTypeMutation creates new mutation for $n.Name. +func newFieldTypeMutation(c config, op Op) *FieldTypeMutation { + return &FieldTypeMutation{ + config: c, + op: op, + typ: TypeFieldType, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m FieldTypeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m FieldTypeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *FieldTypeMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetInt sets the int field. +func (m *FieldTypeMutation) SetInt(i int) { + m.int = &i + m.addint = nil +} + +// Int returns the int value in the mutation. +func (m *FieldTypeMutation) Int() (r int, exists bool) { + v := m.int + if v == nil { + return + } + return *v, true +} + +// AddInt adds i to int. +func (m *FieldTypeMutation) AddInt(i int) { + if m.addint != nil { + *m.addint += i + } else { + m.addint = &i + } +} + +// AddedInt returns the value that was added to the int field in this mutation. +func (m *FieldTypeMutation) AddedInt() (r int, exists bool) { + v := m.addint + if v == nil { + return + } + return *v, true +} + +// ResetInt reset all changes of the int field. +func (m *FieldTypeMutation) ResetInt() { + m.int = nil + m.addint = nil +} + +// SetInt8 sets the int8 field. +func (m *FieldTypeMutation) SetInt8(i int8) { + m.int8 = &i + m.addint8 = nil +} + +// Int8 returns the int8 value in the mutation. +func (m *FieldTypeMutation) Int8() (r int8, exists bool) { + v := m.int8 + if v == nil { + return + } + return *v, true +} + +// AddInt8 adds i to int8. +func (m *FieldTypeMutation) AddInt8(i int8) { + if m.addint8 != nil { + *m.addint8 += i + } else { + m.addint8 = &i + } +} + +// AddedInt8 returns the value that was added to the int8 field in this mutation. +func (m *FieldTypeMutation) AddedInt8() (r int8, exists bool) { + v := m.addint8 + if v == nil { + return + } + return *v, true +} + +// ResetInt8 reset all changes of the int8 field. +func (m *FieldTypeMutation) ResetInt8() { + m.int8 = nil + m.addint8 = nil +} + +// SetInt16 sets the int16 field. +func (m *FieldTypeMutation) SetInt16(i int16) { + m.int16 = &i + m.addint16 = nil +} + +// Int16 returns the int16 value in the mutation. +func (m *FieldTypeMutation) Int16() (r int16, exists bool) { + v := m.int16 + if v == nil { + return + } + return *v, true +} + +// AddInt16 adds i to int16. +func (m *FieldTypeMutation) AddInt16(i int16) { + if m.addint16 != nil { + *m.addint16 += i + } else { + m.addint16 = &i + } +} + +// AddedInt16 returns the value that was added to the int16 field in this mutation. +func (m *FieldTypeMutation) AddedInt16() (r int16, exists bool) { + v := m.addint16 + if v == nil { + return + } + return *v, true +} + +// ResetInt16 reset all changes of the int16 field. +func (m *FieldTypeMutation) ResetInt16() { + m.int16 = nil + m.addint16 = nil +} + +// SetInt32 sets the int32 field. +func (m *FieldTypeMutation) SetInt32(i int32) { + m.int32 = &i + m.addint32 = nil +} + +// Int32 returns the int32 value in the mutation. +func (m *FieldTypeMutation) Int32() (r int32, exists bool) { + v := m.int32 + if v == nil { + return + } + return *v, true +} + +// AddInt32 adds i to int32. +func (m *FieldTypeMutation) AddInt32(i int32) { + if m.addint32 != nil { + *m.addint32 += i + } else { + m.addint32 = &i + } +} + +// AddedInt32 returns the value that was added to the int32 field in this mutation. +func (m *FieldTypeMutation) AddedInt32() (r int32, exists bool) { + v := m.addint32 + if v == nil { + return + } + return *v, true +} + +// ResetInt32 reset all changes of the int32 field. +func (m *FieldTypeMutation) ResetInt32() { + m.int32 = nil + m.addint32 = nil +} + +// SetInt64 sets the int64 field. +func (m *FieldTypeMutation) SetInt64(i int64) { + m.int64 = &i + m.addint64 = nil +} + +// Int64 returns the int64 value in the mutation. +func (m *FieldTypeMutation) Int64() (r int64, exists bool) { + v := m.int64 + if v == nil { + return + } + return *v, true +} + +// AddInt64 adds i to int64. +func (m *FieldTypeMutation) AddInt64(i int64) { + if m.addint64 != nil { + *m.addint64 += i + } else { + m.addint64 = &i + } +} + +// AddedInt64 returns the value that was added to the int64 field in this mutation. +func (m *FieldTypeMutation) AddedInt64() (r int64, exists bool) { + v := m.addint64 + if v == nil { + return + } + return *v, true +} + +// ResetInt64 reset all changes of the int64 field. +func (m *FieldTypeMutation) ResetInt64() { + m.int64 = nil + m.addint64 = nil +} + +// SetOptionalInt sets the optional_int field. +func (m *FieldTypeMutation) SetOptionalInt(i int) { + m.optional_int = &i + m.addoptional_int = nil +} + +// OptionalInt returns the optional_int value in the mutation. +func (m *FieldTypeMutation) OptionalInt() (r int, exists bool) { + v := m.optional_int + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt adds i to optional_int. +func (m *FieldTypeMutation) AddOptionalInt(i int) { + if m.addoptional_int != nil { + *m.addoptional_int += i + } else { + m.addoptional_int = &i + } +} + +// AddedOptionalInt returns the value that was added to the optional_int field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt() (r int, exists bool) { + v := m.addoptional_int + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt clears the value of optional_int. +func (m *FieldTypeMutation) ClearOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + m.clearedFields[fieldtype.FieldOptionalInt] = true +} + +// OptionalIntCleared returns if the field optional_int was cleared in this mutation. +func (m *FieldTypeMutation) OptionalIntCleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt] +} + +// ResetOptionalInt reset all changes of the optional_int field. +func (m *FieldTypeMutation) ResetOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt) +} + +// SetOptionalInt8 sets the optional_int8 field. +func (m *FieldTypeMutation) SetOptionalInt8(i int8) { + m.optional_int8 = &i + m.addoptional_int8 = nil +} + +// OptionalInt8 returns the optional_int8 value in the mutation. +func (m *FieldTypeMutation) OptionalInt8() (r int8, exists bool) { + v := m.optional_int8 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt8 adds i to optional_int8. +func (m *FieldTypeMutation) AddOptionalInt8(i int8) { + if m.addoptional_int8 != nil { + *m.addoptional_int8 += i + } else { + m.addoptional_int8 = &i + } +} + +// AddedOptionalInt8 returns the value that was added to the optional_int8 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt8() (r int8, exists bool) { + v := m.addoptional_int8 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt8 clears the value of optional_int8. +func (m *FieldTypeMutation) ClearOptionalInt8() { + m.optional_int8 = nil + m.addoptional_int8 = nil + m.clearedFields[fieldtype.FieldOptionalInt8] = true +} + +// OptionalInt8Cleared returns if the field optional_int8 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt8Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt8] +} + +// ResetOptionalInt8 reset all changes of the optional_int8 field. +func (m *FieldTypeMutation) ResetOptionalInt8() { + m.optional_int8 = nil + m.addoptional_int8 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt8) +} + +// SetOptionalInt16 sets the optional_int16 field. +func (m *FieldTypeMutation) SetOptionalInt16(i int16) { + m.optional_int16 = &i + m.addoptional_int16 = nil +} + +// OptionalInt16 returns the optional_int16 value in the mutation. +func (m *FieldTypeMutation) OptionalInt16() (r int16, exists bool) { + v := m.optional_int16 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt16 adds i to optional_int16. +func (m *FieldTypeMutation) AddOptionalInt16(i int16) { + if m.addoptional_int16 != nil { + *m.addoptional_int16 += i + } else { + m.addoptional_int16 = &i + } +} + +// AddedOptionalInt16 returns the value that was added to the optional_int16 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt16() (r int16, exists bool) { + v := m.addoptional_int16 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt16 clears the value of optional_int16. +func (m *FieldTypeMutation) ClearOptionalInt16() { + m.optional_int16 = nil + m.addoptional_int16 = nil + m.clearedFields[fieldtype.FieldOptionalInt16] = true +} + +// OptionalInt16Cleared returns if the field optional_int16 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt16Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt16] +} + +// ResetOptionalInt16 reset all changes of the optional_int16 field. +func (m *FieldTypeMutation) ResetOptionalInt16() { + m.optional_int16 = nil + m.addoptional_int16 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt16) +} + +// SetOptionalInt32 sets the optional_int32 field. +func (m *FieldTypeMutation) SetOptionalInt32(i int32) { + m.optional_int32 = &i + m.addoptional_int32 = nil +} + +// OptionalInt32 returns the optional_int32 value in the mutation. +func (m *FieldTypeMutation) OptionalInt32() (r int32, exists bool) { + v := m.optional_int32 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt32 adds i to optional_int32. +func (m *FieldTypeMutation) AddOptionalInt32(i int32) { + if m.addoptional_int32 != nil { + *m.addoptional_int32 += i + } else { + m.addoptional_int32 = &i + } +} + +// AddedOptionalInt32 returns the value that was added to the optional_int32 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt32() (r int32, exists bool) { + v := m.addoptional_int32 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt32 clears the value of optional_int32. +func (m *FieldTypeMutation) ClearOptionalInt32() { + m.optional_int32 = nil + m.addoptional_int32 = nil + m.clearedFields[fieldtype.FieldOptionalInt32] = true +} + +// OptionalInt32Cleared returns if the field optional_int32 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt32Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt32] +} + +// ResetOptionalInt32 reset all changes of the optional_int32 field. +func (m *FieldTypeMutation) ResetOptionalInt32() { + m.optional_int32 = nil + m.addoptional_int32 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt32) +} + +// SetOptionalInt64 sets the optional_int64 field. +func (m *FieldTypeMutation) SetOptionalInt64(i int64) { + m.optional_int64 = &i + m.addoptional_int64 = nil +} + +// OptionalInt64 returns the optional_int64 value in the mutation. +func (m *FieldTypeMutation) OptionalInt64() (r int64, exists bool) { + v := m.optional_int64 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt64 adds i to optional_int64. +func (m *FieldTypeMutation) AddOptionalInt64(i int64) { + if m.addoptional_int64 != nil { + *m.addoptional_int64 += i + } else { + m.addoptional_int64 = &i + } +} + +// AddedOptionalInt64 returns the value that was added to the optional_int64 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt64() (r int64, exists bool) { + v := m.addoptional_int64 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt64 clears the value of optional_int64. +func (m *FieldTypeMutation) ClearOptionalInt64() { + m.optional_int64 = nil + m.addoptional_int64 = nil + m.clearedFields[fieldtype.FieldOptionalInt64] = true +} + +// OptionalInt64Cleared returns if the field optional_int64 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt64Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt64] +} + +// ResetOptionalInt64 reset all changes of the optional_int64 field. +func (m *FieldTypeMutation) ResetOptionalInt64() { + m.optional_int64 = nil + m.addoptional_int64 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt64) +} + +// SetNillableInt sets the nillable_int field. +func (m *FieldTypeMutation) SetNillableInt(i int) { + m.nillable_int = &i + m.addnillable_int = nil +} + +// NillableInt returns the nillable_int value in the mutation. +func (m *FieldTypeMutation) NillableInt() (r int, exists bool) { + v := m.nillable_int + if v == nil { + return + } + return *v, true +} + +// AddNillableInt adds i to nillable_int. +func (m *FieldTypeMutation) AddNillableInt(i int) { + if m.addnillable_int != nil { + *m.addnillable_int += i + } else { + m.addnillable_int = &i + } +} + +// AddedNillableInt returns the value that was added to the nillable_int field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt() (r int, exists bool) { + v := m.addnillable_int + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt clears the value of nillable_int. +func (m *FieldTypeMutation) ClearNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + m.clearedFields[fieldtype.FieldNillableInt] = true +} + +// NillableIntCleared returns if the field nillable_int was cleared in this mutation. +func (m *FieldTypeMutation) NillableIntCleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt] +} + +// ResetNillableInt reset all changes of the nillable_int field. +func (m *FieldTypeMutation) ResetNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + delete(m.clearedFields, fieldtype.FieldNillableInt) +} + +// SetNillableInt8 sets the nillable_int8 field. +func (m *FieldTypeMutation) SetNillableInt8(i int8) { + m.nillable_int8 = &i + m.addnillable_int8 = nil +} + +// NillableInt8 returns the nillable_int8 value in the mutation. +func (m *FieldTypeMutation) NillableInt8() (r int8, exists bool) { + v := m.nillable_int8 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt8 adds i to nillable_int8. +func (m *FieldTypeMutation) AddNillableInt8(i int8) { + if m.addnillable_int8 != nil { + *m.addnillable_int8 += i + } else { + m.addnillable_int8 = &i + } +} + +// AddedNillableInt8 returns the value that was added to the nillable_int8 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt8() (r int8, exists bool) { + v := m.addnillable_int8 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt8 clears the value of nillable_int8. +func (m *FieldTypeMutation) ClearNillableInt8() { + m.nillable_int8 = nil + m.addnillable_int8 = nil + m.clearedFields[fieldtype.FieldNillableInt8] = true +} + +// NillableInt8Cleared returns if the field nillable_int8 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt8Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt8] +} + +// ResetNillableInt8 reset all changes of the nillable_int8 field. +func (m *FieldTypeMutation) ResetNillableInt8() { + m.nillable_int8 = nil + m.addnillable_int8 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt8) +} + +// SetNillableInt16 sets the nillable_int16 field. +func (m *FieldTypeMutation) SetNillableInt16(i int16) { + m.nillable_int16 = &i + m.addnillable_int16 = nil +} + +// NillableInt16 returns the nillable_int16 value in the mutation. +func (m *FieldTypeMutation) NillableInt16() (r int16, exists bool) { + v := m.nillable_int16 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt16 adds i to nillable_int16. +func (m *FieldTypeMutation) AddNillableInt16(i int16) { + if m.addnillable_int16 != nil { + *m.addnillable_int16 += i + } else { + m.addnillable_int16 = &i + } +} + +// AddedNillableInt16 returns the value that was added to the nillable_int16 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt16() (r int16, exists bool) { + v := m.addnillable_int16 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt16 clears the value of nillable_int16. +func (m *FieldTypeMutation) ClearNillableInt16() { + m.nillable_int16 = nil + m.addnillable_int16 = nil + m.clearedFields[fieldtype.FieldNillableInt16] = true +} + +// NillableInt16Cleared returns if the field nillable_int16 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt16Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt16] +} + +// ResetNillableInt16 reset all changes of the nillable_int16 field. +func (m *FieldTypeMutation) ResetNillableInt16() { + m.nillable_int16 = nil + m.addnillable_int16 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt16) +} + +// SetNillableInt32 sets the nillable_int32 field. +func (m *FieldTypeMutation) SetNillableInt32(i int32) { + m.nillable_int32 = &i + m.addnillable_int32 = nil +} + +// NillableInt32 returns the nillable_int32 value in the mutation. +func (m *FieldTypeMutation) NillableInt32() (r int32, exists bool) { + v := m.nillable_int32 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt32 adds i to nillable_int32. +func (m *FieldTypeMutation) AddNillableInt32(i int32) { + if m.addnillable_int32 != nil { + *m.addnillable_int32 += i + } else { + m.addnillable_int32 = &i + } +} + +// AddedNillableInt32 returns the value that was added to the nillable_int32 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt32() (r int32, exists bool) { + v := m.addnillable_int32 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt32 clears the value of nillable_int32. +func (m *FieldTypeMutation) ClearNillableInt32() { + m.nillable_int32 = nil + m.addnillable_int32 = nil + m.clearedFields[fieldtype.FieldNillableInt32] = true +} + +// NillableInt32Cleared returns if the field nillable_int32 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt32Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt32] +} + +// ResetNillableInt32 reset all changes of the nillable_int32 field. +func (m *FieldTypeMutation) ResetNillableInt32() { + m.nillable_int32 = nil + m.addnillable_int32 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt32) +} + +// SetNillableInt64 sets the nillable_int64 field. +func (m *FieldTypeMutation) SetNillableInt64(i int64) { + m.nillable_int64 = &i + m.addnillable_int64 = nil +} + +// NillableInt64 returns the nillable_int64 value in the mutation. +func (m *FieldTypeMutation) NillableInt64() (r int64, exists bool) { + v := m.nillable_int64 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt64 adds i to nillable_int64. +func (m *FieldTypeMutation) AddNillableInt64(i int64) { + if m.addnillable_int64 != nil { + *m.addnillable_int64 += i + } else { + m.addnillable_int64 = &i + } +} + +// AddedNillableInt64 returns the value that was added to the nillable_int64 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt64() (r int64, exists bool) { + v := m.addnillable_int64 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt64 clears the value of nillable_int64. +func (m *FieldTypeMutation) ClearNillableInt64() { + m.nillable_int64 = nil + m.addnillable_int64 = nil + m.clearedFields[fieldtype.FieldNillableInt64] = true +} + +// NillableInt64Cleared returns if the field nillable_int64 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt64Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt64] +} + +// ResetNillableInt64 reset all changes of the nillable_int64 field. +func (m *FieldTypeMutation) ResetNillableInt64() { + m.nillable_int64 = nil + m.addnillable_int64 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt64) +} + +// SetValidateOptionalInt32 sets the validate_optional_int32 field. +func (m *FieldTypeMutation) SetValidateOptionalInt32(i int32) { + m.validate_optional_int32 = &i + m.addvalidate_optional_int32 = nil +} + +// ValidateOptionalInt32 returns the validate_optional_int32 value in the mutation. +func (m *FieldTypeMutation) ValidateOptionalInt32() (r int32, exists bool) { + v := m.validate_optional_int32 + if v == nil { + return + } + return *v, true +} + +// AddValidateOptionalInt32 adds i to validate_optional_int32. +func (m *FieldTypeMutation) AddValidateOptionalInt32(i int32) { + if m.addvalidate_optional_int32 != nil { + *m.addvalidate_optional_int32 += i + } else { + m.addvalidate_optional_int32 = &i + } +} + +// AddedValidateOptionalInt32 returns the value that was added to the validate_optional_int32 field in this mutation. +func (m *FieldTypeMutation) AddedValidateOptionalInt32() (r int32, exists bool) { + v := m.addvalidate_optional_int32 + if v == nil { + return + } + return *v, true +} + +// ClearValidateOptionalInt32 clears the value of validate_optional_int32. +func (m *FieldTypeMutation) ClearValidateOptionalInt32() { + m.validate_optional_int32 = nil + m.addvalidate_optional_int32 = nil + m.clearedFields[fieldtype.FieldValidateOptionalInt32] = true +} + +// ValidateOptionalInt32Cleared returns if the field validate_optional_int32 was cleared in this mutation. +func (m *FieldTypeMutation) ValidateOptionalInt32Cleared() bool { + return m.clearedFields[fieldtype.FieldValidateOptionalInt32] +} + +// ResetValidateOptionalInt32 reset all changes of the validate_optional_int32 field. +func (m *FieldTypeMutation) ResetValidateOptionalInt32() { + m.validate_optional_int32 = nil + m.addvalidate_optional_int32 = nil + delete(m.clearedFields, fieldtype.FieldValidateOptionalInt32) +} + +// SetOptionalUint sets the optional_uint field. +func (m *FieldTypeMutation) SetOptionalUint(u uint) { + m.optional_uint = &u + m.addoptional_uint = nil +} + +// OptionalUint returns the optional_uint value in the mutation. +func (m *FieldTypeMutation) OptionalUint() (r uint, exists bool) { + v := m.optional_uint + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint adds u to optional_uint. +func (m *FieldTypeMutation) AddOptionalUint(u uint) { + if m.addoptional_uint != nil { + *m.addoptional_uint += u + } else { + m.addoptional_uint = &u + } +} + +// AddedOptionalUint returns the value that was added to the optional_uint field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint() (r uint, exists bool) { + v := m.addoptional_uint + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint clears the value of optional_uint. +func (m *FieldTypeMutation) ClearOptionalUint() { + m.optional_uint = nil + m.addoptional_uint = nil + m.clearedFields[fieldtype.FieldOptionalUint] = true +} + +// OptionalUintCleared returns if the field optional_uint was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUintCleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint] +} + +// ResetOptionalUint reset all changes of the optional_uint field. +func (m *FieldTypeMutation) ResetOptionalUint() { + m.optional_uint = nil + m.addoptional_uint = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint) +} + +// SetOptionalUint8 sets the optional_uint8 field. +func (m *FieldTypeMutation) SetOptionalUint8(u uint8) { + m.optional_uint8 = &u + m.addoptional_uint8 = nil +} + +// OptionalUint8 returns the optional_uint8 value in the mutation. +func (m *FieldTypeMutation) OptionalUint8() (r uint8, exists bool) { + v := m.optional_uint8 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint8 adds u to optional_uint8. +func (m *FieldTypeMutation) AddOptionalUint8(u uint8) { + if m.addoptional_uint8 != nil { + *m.addoptional_uint8 += u + } else { + m.addoptional_uint8 = &u + } +} + +// AddedOptionalUint8 returns the value that was added to the optional_uint8 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint8() (r uint8, exists bool) { + v := m.addoptional_uint8 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint8 clears the value of optional_uint8. +func (m *FieldTypeMutation) ClearOptionalUint8() { + m.optional_uint8 = nil + m.addoptional_uint8 = nil + m.clearedFields[fieldtype.FieldOptionalUint8] = true +} + +// OptionalUint8Cleared returns if the field optional_uint8 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint8Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint8] +} + +// ResetOptionalUint8 reset all changes of the optional_uint8 field. +func (m *FieldTypeMutation) ResetOptionalUint8() { + m.optional_uint8 = nil + m.addoptional_uint8 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint8) +} + +// SetOptionalUint16 sets the optional_uint16 field. +func (m *FieldTypeMutation) SetOptionalUint16(u uint16) { + m.optional_uint16 = &u + m.addoptional_uint16 = nil +} + +// OptionalUint16 returns the optional_uint16 value in the mutation. +func (m *FieldTypeMutation) OptionalUint16() (r uint16, exists bool) { + v := m.optional_uint16 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint16 adds u to optional_uint16. +func (m *FieldTypeMutation) AddOptionalUint16(u uint16) { + if m.addoptional_uint16 != nil { + *m.addoptional_uint16 += u + } else { + m.addoptional_uint16 = &u + } +} + +// AddedOptionalUint16 returns the value that was added to the optional_uint16 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint16() (r uint16, exists bool) { + v := m.addoptional_uint16 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint16 clears the value of optional_uint16. +func (m *FieldTypeMutation) ClearOptionalUint16() { + m.optional_uint16 = nil + m.addoptional_uint16 = nil + m.clearedFields[fieldtype.FieldOptionalUint16] = true +} + +// OptionalUint16Cleared returns if the field optional_uint16 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint16Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint16] +} + +// ResetOptionalUint16 reset all changes of the optional_uint16 field. +func (m *FieldTypeMutation) ResetOptionalUint16() { + m.optional_uint16 = nil + m.addoptional_uint16 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint16) +} + +// SetOptionalUint32 sets the optional_uint32 field. +func (m *FieldTypeMutation) SetOptionalUint32(u uint32) { + m.optional_uint32 = &u + m.addoptional_uint32 = nil +} + +// OptionalUint32 returns the optional_uint32 value in the mutation. +func (m *FieldTypeMutation) OptionalUint32() (r uint32, exists bool) { + v := m.optional_uint32 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint32 adds u to optional_uint32. +func (m *FieldTypeMutation) AddOptionalUint32(u uint32) { + if m.addoptional_uint32 != nil { + *m.addoptional_uint32 += u + } else { + m.addoptional_uint32 = &u + } +} + +// AddedOptionalUint32 returns the value that was added to the optional_uint32 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint32() (r uint32, exists bool) { + v := m.addoptional_uint32 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint32 clears the value of optional_uint32. +func (m *FieldTypeMutation) ClearOptionalUint32() { + m.optional_uint32 = nil + m.addoptional_uint32 = nil + m.clearedFields[fieldtype.FieldOptionalUint32] = true +} + +// OptionalUint32Cleared returns if the field optional_uint32 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint32Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint32] +} + +// ResetOptionalUint32 reset all changes of the optional_uint32 field. +func (m *FieldTypeMutation) ResetOptionalUint32() { + m.optional_uint32 = nil + m.addoptional_uint32 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint32) +} + +// SetOptionalUint64 sets the optional_uint64 field. +func (m *FieldTypeMutation) SetOptionalUint64(u uint64) { + m.optional_uint64 = &u + m.addoptional_uint64 = nil +} + +// OptionalUint64 returns the optional_uint64 value in the mutation. +func (m *FieldTypeMutation) OptionalUint64() (r uint64, exists bool) { + v := m.optional_uint64 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint64 adds u to optional_uint64. +func (m *FieldTypeMutation) AddOptionalUint64(u uint64) { + if m.addoptional_uint64 != nil { + *m.addoptional_uint64 += u + } else { + m.addoptional_uint64 = &u + } +} + +// AddedOptionalUint64 returns the value that was added to the optional_uint64 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint64() (r uint64, exists bool) { + v := m.addoptional_uint64 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint64 clears the value of optional_uint64. +func (m *FieldTypeMutation) ClearOptionalUint64() { + m.optional_uint64 = nil + m.addoptional_uint64 = nil + m.clearedFields[fieldtype.FieldOptionalUint64] = true +} + +// OptionalUint64Cleared returns if the field optional_uint64 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint64Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint64] +} + +// ResetOptionalUint64 reset all changes of the optional_uint64 field. +func (m *FieldTypeMutation) ResetOptionalUint64() { + m.optional_uint64 = nil + m.addoptional_uint64 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint64) +} + +// SetState sets the state field. +func (m *FieldTypeMutation) SetState(f fieldtype.State) { + m.state = &f +} + +// State returns the state value in the mutation. +func (m *FieldTypeMutation) State() (r fieldtype.State, exists bool) { + v := m.state + if v == nil { + return + } + return *v, true +} + +// ClearState clears the value of state. +func (m *FieldTypeMutation) ClearState() { + m.state = nil + m.clearedFields[fieldtype.FieldState] = true +} + +// StateCleared returns if the field state was cleared in this mutation. +func (m *FieldTypeMutation) StateCleared() bool { + return m.clearedFields[fieldtype.FieldState] +} + +// ResetState reset all changes of the state field. +func (m *FieldTypeMutation) ResetState() { + m.state = nil + delete(m.clearedFields, fieldtype.FieldState) +} + +// SetOptionalFloat sets the optional_float field. +func (m *FieldTypeMutation) SetOptionalFloat(f float64) { + m.optional_float = &f + m.addoptional_float = nil +} + +// OptionalFloat returns the optional_float value in the mutation. +func (m *FieldTypeMutation) OptionalFloat() (r float64, exists bool) { + v := m.optional_float + if v == nil { + return + } + return *v, true +} + +// AddOptionalFloat adds f to optional_float. +func (m *FieldTypeMutation) AddOptionalFloat(f float64) { + if m.addoptional_float != nil { + *m.addoptional_float += f + } else { + m.addoptional_float = &f + } +} + +// AddedOptionalFloat returns the value that was added to the optional_float field in this mutation. +func (m *FieldTypeMutation) AddedOptionalFloat() (r float64, exists bool) { + v := m.addoptional_float + if v == nil { + return + } + return *v, true +} + +// ClearOptionalFloat clears the value of optional_float. +func (m *FieldTypeMutation) ClearOptionalFloat() { + m.optional_float = nil + m.addoptional_float = nil + m.clearedFields[fieldtype.FieldOptionalFloat] = true +} + +// OptionalFloatCleared returns if the field optional_float was cleared in this mutation. +func (m *FieldTypeMutation) OptionalFloatCleared() bool { + return m.clearedFields[fieldtype.FieldOptionalFloat] +} + +// ResetOptionalFloat reset all changes of the optional_float field. +func (m *FieldTypeMutation) ResetOptionalFloat() { + m.optional_float = nil + m.addoptional_float = nil + delete(m.clearedFields, fieldtype.FieldOptionalFloat) +} + +// SetOptionalFloat32 sets the optional_float32 field. +func (m *FieldTypeMutation) SetOptionalFloat32(f float32) { + m.optional_float32 = &f + m.addoptional_float32 = nil +} + +// OptionalFloat32 returns the optional_float32 value in the mutation. +func (m *FieldTypeMutation) OptionalFloat32() (r float32, exists bool) { + v := m.optional_float32 + if v == nil { + return + } + return *v, true +} + +// AddOptionalFloat32 adds f to optional_float32. +func (m *FieldTypeMutation) AddOptionalFloat32(f float32) { + if m.addoptional_float32 != nil { + *m.addoptional_float32 += f + } else { + m.addoptional_float32 = &f + } +} + +// AddedOptionalFloat32 returns the value that was added to the optional_float32 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalFloat32() (r float32, exists bool) { + v := m.addoptional_float32 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalFloat32 clears the value of optional_float32. +func (m *FieldTypeMutation) ClearOptionalFloat32() { + m.optional_float32 = nil + m.addoptional_float32 = nil + m.clearedFields[fieldtype.FieldOptionalFloat32] = true +} + +// OptionalFloat32Cleared returns if the field optional_float32 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalFloat32Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalFloat32] +} + +// ResetOptionalFloat32 reset all changes of the optional_float32 field. +func (m *FieldTypeMutation) ResetOptionalFloat32() { + m.optional_float32 = nil + m.addoptional_float32 = nil + delete(m.clearedFields, fieldtype.FieldOptionalFloat32) +} + +// Op returns the operation name. +func (m *FieldTypeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (FieldType). +func (m *FieldTypeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *FieldTypeMutation) Fields() []string { + fields := make([]string, 0, 24) + if m.int != nil { + fields = append(fields, fieldtype.FieldInt) + } + if m.int8 != nil { + fields = append(fields, fieldtype.FieldInt8) + } + if m.int16 != nil { + fields = append(fields, fieldtype.FieldInt16) + } + if m.int32 != nil { + fields = append(fields, fieldtype.FieldInt32) + } + if m.int64 != nil { + fields = append(fields, fieldtype.FieldInt64) + } + if m.optional_int != nil { + fields = append(fields, fieldtype.FieldOptionalInt) + } + if m.optional_int8 != nil { + fields = append(fields, fieldtype.FieldOptionalInt8) + } + if m.optional_int16 != nil { + fields = append(fields, fieldtype.FieldOptionalInt16) + } + if m.optional_int32 != nil { + fields = append(fields, fieldtype.FieldOptionalInt32) + } + if m.optional_int64 != nil { + fields = append(fields, fieldtype.FieldOptionalInt64) + } + if m.nillable_int != nil { + fields = append(fields, fieldtype.FieldNillableInt) + } + if m.nillable_int8 != nil { + fields = append(fields, fieldtype.FieldNillableInt8) + } + if m.nillable_int16 != nil { + fields = append(fields, fieldtype.FieldNillableInt16) + } + if m.nillable_int32 != nil { + fields = append(fields, fieldtype.FieldNillableInt32) + } + if m.nillable_int64 != nil { + fields = append(fields, fieldtype.FieldNillableInt64) + } + if m.validate_optional_int32 != nil { + fields = append(fields, fieldtype.FieldValidateOptionalInt32) + } + if m.optional_uint != nil { + fields = append(fields, fieldtype.FieldOptionalUint) + } + if m.optional_uint8 != nil { + fields = append(fields, fieldtype.FieldOptionalUint8) + } + if m.optional_uint16 != nil { + fields = append(fields, fieldtype.FieldOptionalUint16) + } + if m.optional_uint32 != nil { + fields = append(fields, fieldtype.FieldOptionalUint32) + } + if m.optional_uint64 != nil { + fields = append(fields, fieldtype.FieldOptionalUint64) + } + if m.state != nil { + fields = append(fields, fieldtype.FieldState) + } + if m.optional_float != nil { + fields = append(fields, fieldtype.FieldOptionalFloat) + } + if m.optional_float32 != nil { + fields = append(fields, fieldtype.FieldOptionalFloat32) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *FieldTypeMutation) Field(name string) (ent.Value, bool) { + switch name { + case fieldtype.FieldInt: + return m.Int() + case fieldtype.FieldInt8: + return m.Int8() + case fieldtype.FieldInt16: + return m.Int16() + case fieldtype.FieldInt32: + return m.Int32() + case fieldtype.FieldInt64: + return m.Int64() + case fieldtype.FieldOptionalInt: + return m.OptionalInt() + case fieldtype.FieldOptionalInt8: + return m.OptionalInt8() + case fieldtype.FieldOptionalInt16: + return m.OptionalInt16() + case fieldtype.FieldOptionalInt32: + return m.OptionalInt32() + case fieldtype.FieldOptionalInt64: + return m.OptionalInt64() + case fieldtype.FieldNillableInt: + return m.NillableInt() + case fieldtype.FieldNillableInt8: + return m.NillableInt8() + case fieldtype.FieldNillableInt16: + return m.NillableInt16() + case fieldtype.FieldNillableInt32: + return m.NillableInt32() + case fieldtype.FieldNillableInt64: + return m.NillableInt64() + case fieldtype.FieldValidateOptionalInt32: + return m.ValidateOptionalInt32() + case fieldtype.FieldOptionalUint: + return m.OptionalUint() + case fieldtype.FieldOptionalUint8: + return m.OptionalUint8() + case fieldtype.FieldOptionalUint16: + return m.OptionalUint16() + case fieldtype.FieldOptionalUint32: + return m.OptionalUint32() + case fieldtype.FieldOptionalUint64: + return m.OptionalUint64() + case fieldtype.FieldState: + return m.State() + case fieldtype.FieldOptionalFloat: + return m.OptionalFloat() + case fieldtype.FieldOptionalFloat32: + return m.OptionalFloat32() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FieldTypeMutation) SetField(name string, value ent.Value) error { + switch name { + case fieldtype.FieldInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt(v) + return nil + case fieldtype.FieldInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt8(v) + return nil + case fieldtype.FieldInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt16(v) + return nil + case fieldtype.FieldInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt32(v) + return nil + case fieldtype.FieldInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt64(v) + return nil + case fieldtype.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt(v) + return nil + case fieldtype.FieldOptionalInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt8(v) + return nil + case fieldtype.FieldOptionalInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt16(v) + return nil + case fieldtype.FieldOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt32(v) + return nil + case fieldtype.FieldOptionalInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt64(v) + return nil + case fieldtype.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt(v) + return nil + case fieldtype.FieldNillableInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt8(v) + return nil + case fieldtype.FieldNillableInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt16(v) + return nil + case fieldtype.FieldNillableInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt32(v) + return nil + case fieldtype.FieldNillableInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt64(v) + return nil + case fieldtype.FieldValidateOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValidateOptionalInt32(v) + return nil + case fieldtype.FieldOptionalUint: + v, ok := value.(uint) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint(v) + return nil + case fieldtype.FieldOptionalUint8: + v, ok := value.(uint8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint8(v) + return nil + case fieldtype.FieldOptionalUint16: + v, ok := value.(uint16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint16(v) + return nil + case fieldtype.FieldOptionalUint32: + v, ok := value.(uint32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint32(v) + return nil + case fieldtype.FieldOptionalUint64: + v, ok := value.(uint64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint64(v) + return nil + case fieldtype.FieldState: + v, ok := value.(fieldtype.State) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetState(v) + return nil + case fieldtype.FieldOptionalFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalFloat(v) + return nil + case fieldtype.FieldOptionalFloat32: + v, ok := value.(float32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalFloat32(v) + return nil + } + return fmt.Errorf("unknown FieldType field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *FieldTypeMutation) AddedFields() []string { + var fields []string + if m.addint != nil { + fields = append(fields, fieldtype.FieldInt) + } + if m.addint8 != nil { + fields = append(fields, fieldtype.FieldInt8) + } + if m.addint16 != nil { + fields = append(fields, fieldtype.FieldInt16) + } + if m.addint32 != nil { + fields = append(fields, fieldtype.FieldInt32) + } + if m.addint64 != nil { + fields = append(fields, fieldtype.FieldInt64) + } + if m.addoptional_int != nil { + fields = append(fields, fieldtype.FieldOptionalInt) + } + if m.addoptional_int8 != nil { + fields = append(fields, fieldtype.FieldOptionalInt8) + } + if m.addoptional_int16 != nil { + fields = append(fields, fieldtype.FieldOptionalInt16) + } + if m.addoptional_int32 != nil { + fields = append(fields, fieldtype.FieldOptionalInt32) + } + if m.addoptional_int64 != nil { + fields = append(fields, fieldtype.FieldOptionalInt64) + } + if m.addnillable_int != nil { + fields = append(fields, fieldtype.FieldNillableInt) + } + if m.addnillable_int8 != nil { + fields = append(fields, fieldtype.FieldNillableInt8) + } + if m.addnillable_int16 != nil { + fields = append(fields, fieldtype.FieldNillableInt16) + } + if m.addnillable_int32 != nil { + fields = append(fields, fieldtype.FieldNillableInt32) + } + if m.addnillable_int64 != nil { + fields = append(fields, fieldtype.FieldNillableInt64) + } + if m.addvalidate_optional_int32 != nil { + fields = append(fields, fieldtype.FieldValidateOptionalInt32) + } + if m.addoptional_uint != nil { + fields = append(fields, fieldtype.FieldOptionalUint) + } + if m.addoptional_uint8 != nil { + fields = append(fields, fieldtype.FieldOptionalUint8) + } + if m.addoptional_uint16 != nil { + fields = append(fields, fieldtype.FieldOptionalUint16) + } + if m.addoptional_uint32 != nil { + fields = append(fields, fieldtype.FieldOptionalUint32) + } + if m.addoptional_uint64 != nil { + fields = append(fields, fieldtype.FieldOptionalUint64) + } + if m.addoptional_float != nil { + fields = append(fields, fieldtype.FieldOptionalFloat) + } + if m.addoptional_float32 != nil { + fields = append(fields, fieldtype.FieldOptionalFloat32) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *FieldTypeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case fieldtype.FieldInt: + return m.AddedInt() + case fieldtype.FieldInt8: + return m.AddedInt8() + case fieldtype.FieldInt16: + return m.AddedInt16() + case fieldtype.FieldInt32: + return m.AddedInt32() + case fieldtype.FieldInt64: + return m.AddedInt64() + case fieldtype.FieldOptionalInt: + return m.AddedOptionalInt() + case fieldtype.FieldOptionalInt8: + return m.AddedOptionalInt8() + case fieldtype.FieldOptionalInt16: + return m.AddedOptionalInt16() + case fieldtype.FieldOptionalInt32: + return m.AddedOptionalInt32() + case fieldtype.FieldOptionalInt64: + return m.AddedOptionalInt64() + case fieldtype.FieldNillableInt: + return m.AddedNillableInt() + case fieldtype.FieldNillableInt8: + return m.AddedNillableInt8() + case fieldtype.FieldNillableInt16: + return m.AddedNillableInt16() + case fieldtype.FieldNillableInt32: + return m.AddedNillableInt32() + case fieldtype.FieldNillableInt64: + return m.AddedNillableInt64() + case fieldtype.FieldValidateOptionalInt32: + return m.AddedValidateOptionalInt32() + case fieldtype.FieldOptionalUint: + return m.AddedOptionalUint() + case fieldtype.FieldOptionalUint8: + return m.AddedOptionalUint8() + case fieldtype.FieldOptionalUint16: + return m.AddedOptionalUint16() + case fieldtype.FieldOptionalUint32: + return m.AddedOptionalUint32() + case fieldtype.FieldOptionalUint64: + return m.AddedOptionalUint64() + case fieldtype.FieldOptionalFloat: + return m.AddedOptionalFloat() + case fieldtype.FieldOptionalFloat32: + return m.AddedOptionalFloat32() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FieldTypeMutation) AddField(name string, value ent.Value) error { + switch name { + case fieldtype.FieldInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt(v) + return nil + case fieldtype.FieldInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt8(v) + return nil + case fieldtype.FieldInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt16(v) + return nil + case fieldtype.FieldInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt32(v) + return nil + case fieldtype.FieldInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt64(v) + return nil + case fieldtype.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt(v) + return nil + case fieldtype.FieldOptionalInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt8(v) + return nil + case fieldtype.FieldOptionalInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt16(v) + return nil + case fieldtype.FieldOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt32(v) + return nil + case fieldtype.FieldOptionalInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt64(v) + return nil + case fieldtype.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt(v) + return nil + case fieldtype.FieldNillableInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt8(v) + return nil + case fieldtype.FieldNillableInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt16(v) + return nil + case fieldtype.FieldNillableInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt32(v) + return nil + case fieldtype.FieldNillableInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt64(v) + return nil + case fieldtype.FieldValidateOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValidateOptionalInt32(v) + return nil + case fieldtype.FieldOptionalUint: + v, ok := value.(uint) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint(v) + return nil + case fieldtype.FieldOptionalUint8: + v, ok := value.(uint8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint8(v) + return nil + case fieldtype.FieldOptionalUint16: + v, ok := value.(uint16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint16(v) + return nil + case fieldtype.FieldOptionalUint32: + v, ok := value.(uint32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint32(v) + return nil + case fieldtype.FieldOptionalUint64: + v, ok := value.(uint64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint64(v) + return nil + case fieldtype.FieldOptionalFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalFloat(v) + return nil + case fieldtype.FieldOptionalFloat32: + v, ok := value.(float32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalFloat32(v) + return nil + } + return fmt.Errorf("unknown FieldType numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *FieldTypeMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[fieldtype.FieldOptionalInt] { + fields = append(fields, fieldtype.FieldOptionalInt) + } + if m.clearedFields[fieldtype.FieldOptionalInt8] { + fields = append(fields, fieldtype.FieldOptionalInt8) + } + if m.clearedFields[fieldtype.FieldOptionalInt16] { + fields = append(fields, fieldtype.FieldOptionalInt16) + } + if m.clearedFields[fieldtype.FieldOptionalInt32] { + fields = append(fields, fieldtype.FieldOptionalInt32) + } + if m.clearedFields[fieldtype.FieldOptionalInt64] { + fields = append(fields, fieldtype.FieldOptionalInt64) + } + if m.clearedFields[fieldtype.FieldNillableInt] { + fields = append(fields, fieldtype.FieldNillableInt) + } + if m.clearedFields[fieldtype.FieldNillableInt8] { + fields = append(fields, fieldtype.FieldNillableInt8) + } + if m.clearedFields[fieldtype.FieldNillableInt16] { + fields = append(fields, fieldtype.FieldNillableInt16) + } + if m.clearedFields[fieldtype.FieldNillableInt32] { + fields = append(fields, fieldtype.FieldNillableInt32) + } + if m.clearedFields[fieldtype.FieldNillableInt64] { + fields = append(fields, fieldtype.FieldNillableInt64) + } + if m.clearedFields[fieldtype.FieldValidateOptionalInt32] { + fields = append(fields, fieldtype.FieldValidateOptionalInt32) + } + if m.clearedFields[fieldtype.FieldOptionalUint] { + fields = append(fields, fieldtype.FieldOptionalUint) + } + if m.clearedFields[fieldtype.FieldOptionalUint8] { + fields = append(fields, fieldtype.FieldOptionalUint8) + } + if m.clearedFields[fieldtype.FieldOptionalUint16] { + fields = append(fields, fieldtype.FieldOptionalUint16) + } + if m.clearedFields[fieldtype.FieldOptionalUint32] { + fields = append(fields, fieldtype.FieldOptionalUint32) + } + if m.clearedFields[fieldtype.FieldOptionalUint64] { + fields = append(fields, fieldtype.FieldOptionalUint64) + } + if m.clearedFields[fieldtype.FieldState] { + fields = append(fields, fieldtype.FieldState) + } + if m.clearedFields[fieldtype.FieldOptionalFloat] { + fields = append(fields, fieldtype.FieldOptionalFloat) + } + if m.clearedFields[fieldtype.FieldOptionalFloat32] { + fields = append(fields, fieldtype.FieldOptionalFloat32) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *FieldTypeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *FieldTypeMutation) ClearField(name string) error { + switch name { + case fieldtype.FieldOptionalInt: + m.ClearOptionalInt() + return nil + case fieldtype.FieldOptionalInt8: + m.ClearOptionalInt8() + return nil + case fieldtype.FieldOptionalInt16: + m.ClearOptionalInt16() + return nil + case fieldtype.FieldOptionalInt32: + m.ClearOptionalInt32() + return nil + case fieldtype.FieldOptionalInt64: + m.ClearOptionalInt64() + return nil + case fieldtype.FieldNillableInt: + m.ClearNillableInt() + return nil + case fieldtype.FieldNillableInt8: + m.ClearNillableInt8() + return nil + case fieldtype.FieldNillableInt16: + m.ClearNillableInt16() + return nil + case fieldtype.FieldNillableInt32: + m.ClearNillableInt32() + return nil + case fieldtype.FieldNillableInt64: + m.ClearNillableInt64() + return nil + case fieldtype.FieldValidateOptionalInt32: + m.ClearValidateOptionalInt32() + return nil + case fieldtype.FieldOptionalUint: + m.ClearOptionalUint() + return nil + case fieldtype.FieldOptionalUint8: + m.ClearOptionalUint8() + return nil + case fieldtype.FieldOptionalUint16: + m.ClearOptionalUint16() + return nil + case fieldtype.FieldOptionalUint32: + m.ClearOptionalUint32() + return nil + case fieldtype.FieldOptionalUint64: + m.ClearOptionalUint64() + return nil + case fieldtype.FieldState: + m.ClearState() + return nil + case fieldtype.FieldOptionalFloat: + m.ClearOptionalFloat() + return nil + case fieldtype.FieldOptionalFloat32: + m.ClearOptionalFloat32() + return nil + } + return fmt.Errorf("unknown FieldType nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *FieldTypeMutation) ResetField(name string) error { + switch name { + case fieldtype.FieldInt: + m.ResetInt() + return nil + case fieldtype.FieldInt8: + m.ResetInt8() + return nil + case fieldtype.FieldInt16: + m.ResetInt16() + return nil + case fieldtype.FieldInt32: + m.ResetInt32() + return nil + case fieldtype.FieldInt64: + m.ResetInt64() + return nil + case fieldtype.FieldOptionalInt: + m.ResetOptionalInt() + return nil + case fieldtype.FieldOptionalInt8: + m.ResetOptionalInt8() + return nil + case fieldtype.FieldOptionalInt16: + m.ResetOptionalInt16() + return nil + case fieldtype.FieldOptionalInt32: + m.ResetOptionalInt32() + return nil + case fieldtype.FieldOptionalInt64: + m.ResetOptionalInt64() + return nil + case fieldtype.FieldNillableInt: + m.ResetNillableInt() + return nil + case fieldtype.FieldNillableInt8: + m.ResetNillableInt8() + return nil + case fieldtype.FieldNillableInt16: + m.ResetNillableInt16() + return nil + case fieldtype.FieldNillableInt32: + m.ResetNillableInt32() + return nil + case fieldtype.FieldNillableInt64: + m.ResetNillableInt64() + return nil + case fieldtype.FieldValidateOptionalInt32: + m.ResetValidateOptionalInt32() + return nil + case fieldtype.FieldOptionalUint: + m.ResetOptionalUint() + return nil + case fieldtype.FieldOptionalUint8: + m.ResetOptionalUint8() + return nil + case fieldtype.FieldOptionalUint16: + m.ResetOptionalUint16() + return nil + case fieldtype.FieldOptionalUint32: + m.ResetOptionalUint32() + return nil + case fieldtype.FieldOptionalUint64: + m.ResetOptionalUint64() + return nil + case fieldtype.FieldState: + m.ResetState() + return nil + case fieldtype.FieldOptionalFloat: + m.ResetOptionalFloat() + return nil + case fieldtype.FieldOptionalFloat32: + m.ResetOptionalFloat32() + return nil + } + return fmt.Errorf("unknown FieldType field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *FieldTypeMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *FieldTypeMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *FieldTypeMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *FieldTypeMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *FieldTypeMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *FieldTypeMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *FieldTypeMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown FieldType unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *FieldTypeMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown FieldType edge %s", name) +} + +// FileMutation represents an operation that mutate the Files +// nodes in the graph. +type FileMutation struct { + config + op Op + typ string + id *string + size *int + addsize *int + name *string + user *string + group *string + clearedFields map[string]bool + owner *string + clearedowner bool + _type *string + cleared_type bool +} + +var _ ent.Mutation = (*FileMutation)(nil) + +// newFileMutation creates new mutation for $n.Name. +func newFileMutation(c config, op Op) *FileMutation { + return &FileMutation{ + config: c, + op: op, + typ: TypeFile, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m FileMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m FileMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *FileMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetSize sets the size field. +func (m *FileMutation) SetSize(i int) { + m.size = &i + m.addsize = nil +} + +// Size returns the size value in the mutation. +func (m *FileMutation) Size() (r int, exists bool) { + v := m.size + if v == nil { + return + } + return *v, true +} + +// AddSize adds i to size. +func (m *FileMutation) AddSize(i int) { + if m.addsize != nil { + *m.addsize += i + } else { + m.addsize = &i + } +} + +// AddedSize returns the value that was added to the size field in this mutation. +func (m *FileMutation) AddedSize() (r int, exists bool) { + v := m.addsize + if v == nil { + return + } + return *v, true +} + +// ResetSize reset all changes of the size field. +func (m *FileMutation) ResetSize() { + m.size = nil + m.addsize = nil +} + +// SetName sets the name field. +func (m *FileMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *FileMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *FileMutation) ResetName() { + m.name = nil +} + +// SetUser sets the user field. +func (m *FileMutation) SetUser(s string) { + m.user = &s +} + +// User returns the user value in the mutation. +func (m *FileMutation) User() (r string, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// ClearUser clears the value of user. +func (m *FileMutation) ClearUser() { + m.user = nil + m.clearedFields[file.FieldUser] = true +} + +// UserCleared returns if the field user was cleared in this mutation. +func (m *FileMutation) UserCleared() bool { + return m.clearedFields[file.FieldUser] +} + +// ResetUser reset all changes of the user field. +func (m *FileMutation) ResetUser() { + m.user = nil + delete(m.clearedFields, file.FieldUser) +} + +// SetGroup sets the group field. +func (m *FileMutation) SetGroup(s string) { + m.group = &s +} + +// Group returns the group value in the mutation. +func (m *FileMutation) Group() (r string, exists bool) { + v := m.group + if v == nil { + return + } + return *v, true +} + +// ClearGroup clears the value of group. +func (m *FileMutation) ClearGroup() { + m.group = nil + m.clearedFields[file.FieldGroup] = true +} + +// GroupCleared returns if the field group was cleared in this mutation. +func (m *FileMutation) GroupCleared() bool { + return m.clearedFields[file.FieldGroup] +} + +// ResetGroup reset all changes of the group field. +func (m *FileMutation) ResetGroup() { + m.group = nil + delete(m.clearedFields, file.FieldGroup) +} + +// SetOwnerID sets the owner edge to User by id. +func (m *FileMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *FileMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *FileMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *FileMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *FileMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *FileMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// SetTypeID sets the type edge to FileType by id. +func (m *FileMutation) SetTypeID(id string) { + m._type = &id +} + +// ClearType clears the type edge to FileType. +func (m *FileMutation) ClearType() { + m.cleared_type = true +} + +// TypeCleared returns if the edge type was cleared. +func (m *FileMutation) TypeCleared() bool { + return m.cleared_type +} + +// TypeID returns the type id in the mutation. +func (m *FileMutation) TypeID() (id string, exists bool) { + if m._type != nil { + return *m._type, true + } + return +} + +// TypeIDs returns the type ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// TypeID instead. It exists only for internal usage by the builders. +func (m *FileMutation) TypeIDs() (ids []string) { + if id := m._type; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetType reset all changes of the type edge. +func (m *FileMutation) ResetType() { + m._type = nil + m.cleared_type = false +} + +// Op returns the operation name. +func (m *FileMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (File). +func (m *FileMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *FileMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.size != nil { + fields = append(fields, file.FieldSize) + } + if m.name != nil { + fields = append(fields, file.FieldName) + } + if m.user != nil { + fields = append(fields, file.FieldUser) + } + if m.group != nil { + fields = append(fields, file.FieldGroup) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *FileMutation) Field(name string) (ent.Value, bool) { + switch name { + case file.FieldSize: + return m.Size() + case file.FieldName: + return m.Name() + case file.FieldUser: + return m.User() + case file.FieldGroup: + return m.Group() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileMutation) SetField(name string, value ent.Value) error { + switch name { + case file.FieldSize: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSize(v) + return nil + case file.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case file.FieldUser: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUser(v) + return nil + case file.FieldGroup: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetGroup(v) + return nil + } + return fmt.Errorf("unknown File field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *FileMutation) AddedFields() []string { + var fields []string + if m.addsize != nil { + fields = append(fields, file.FieldSize) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *FileMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case file.FieldSize: + return m.AddedSize() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileMutation) AddField(name string, value ent.Value) error { + switch name { + case file.FieldSize: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSize(v) + return nil + } + return fmt.Errorf("unknown File numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *FileMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[file.FieldUser] { + fields = append(fields, file.FieldUser) + } + if m.clearedFields[file.FieldGroup] { + fields = append(fields, file.FieldGroup) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *FileMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *FileMutation) ClearField(name string) error { + switch name { + case file.FieldUser: + m.ClearUser() + return nil + case file.FieldGroup: + m.ClearGroup() + return nil + } + return fmt.Errorf("unknown File nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *FileMutation) ResetField(name string) error { + switch name { + case file.FieldSize: + m.ResetSize() + return nil + case file.FieldName: + m.ResetName() + return nil + case file.FieldUser: + m.ResetUser() + return nil + case file.FieldGroup: + m.ResetGroup() + return nil + } + return fmt.Errorf("unknown File field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *FileMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.owner != nil { + edges = append(edges, file.EdgeOwner) + } + if m._type != nil { + edges = append(edges, file.EdgeType) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *FileMutation) AddedIDs(name string) []ent.Value { + switch name { + case file.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + case file.EdgeType: + if id := m._type; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *FileMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *FileMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *FileMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedowner { + edges = append(edges, file.EdgeOwner) + } + if m.cleared_type { + edges = append(edges, file.EdgeType) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *FileMutation) EdgeCleared(name string) bool { + switch name { + case file.EdgeOwner: + return m.clearedowner + case file.EdgeType: + return m.cleared_type + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *FileMutation) ClearEdge(name string) error { + switch name { + case file.EdgeOwner: + m.ClearOwner() + return nil + case file.EdgeType: + m.ClearType() + return nil + } + return fmt.Errorf("unknown File unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *FileMutation) ResetEdge(name string) error { + switch name { + case file.EdgeOwner: + m.ResetOwner() + return nil + case file.EdgeType: + m.ResetType() + return nil + } + return fmt.Errorf("unknown File edge %s", name) +} + +// FileTypeMutation represents an operation that mutate the FileTypes +// nodes in the graph. +type FileTypeMutation struct { + config + op Op + typ string + id *string + name *string + clearedFields map[string]bool + files map[string]struct{} + removedfiles map[string]struct{} +} + +var _ ent.Mutation = (*FileTypeMutation)(nil) + +// newFileTypeMutation creates new mutation for $n.Name. +func newFileTypeMutation(c config, op Op) *FileTypeMutation { + return &FileTypeMutation{ + config: c, + op: op, + typ: TypeFileType, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m FileTypeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m FileTypeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *FileTypeMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *FileTypeMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *FileTypeMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *FileTypeMutation) ResetName() { + m.name = nil +} + +// AddFileIDs adds the files edge to File by ids. +func (m *FileTypeMutation) AddFileIDs(ids ...string) { + if m.files == nil { + m.files = make(map[string]struct{}) + } + for i := range ids { + m.files[ids[i]] = struct{}{} + } +} + +// RemoveFileIDs removes the files edge to File by ids. +func (m *FileTypeMutation) RemoveFileIDs(ids ...string) { + if m.removedfiles == nil { + m.removedfiles = make(map[string]struct{}) + } + for i := range ids { + m.removedfiles[ids[i]] = struct{}{} + } +} + +// RemovedFiles returns the removed ids of files. +func (m *FileTypeMutation) RemovedFilesIDs() (ids []string) { + for id := range m.removedfiles { + ids = append(ids, id) + } + return +} + +// FilesIDs returns the files ids in the mutation. +func (m *FileTypeMutation) FilesIDs() (ids []string) { + for id := range m.files { + ids = append(ids, id) + } + return +} + +// ResetFiles reset all changes of the files edge. +func (m *FileTypeMutation) ResetFiles() { + m.files = nil + m.removedfiles = nil +} + +// Op returns the operation name. +func (m *FileTypeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (FileType). +func (m *FileTypeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *FileTypeMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, filetype.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *FileTypeMutation) Field(name string) (ent.Value, bool) { + switch name { + case filetype.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileTypeMutation) SetField(name string, value ent.Value) error { + switch name { + case filetype.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown FileType field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *FileTypeMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *FileTypeMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileTypeMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown FileType numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *FileTypeMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *FileTypeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *FileTypeMutation) ClearField(name string) error { + return fmt.Errorf("unknown FileType nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *FileTypeMutation) ResetField(name string) error { + switch name { + case filetype.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown FileType field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *FileTypeMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.files != nil { + edges = append(edges, filetype.EdgeFiles) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *FileTypeMutation) AddedIDs(name string) []ent.Value { + switch name { + case filetype.EdgeFiles: + ids := make([]ent.Value, 0, len(m.files)) + for id := range m.files { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *FileTypeMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedfiles != nil { + edges = append(edges, filetype.EdgeFiles) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *FileTypeMutation) RemovedIDs(name string) []ent.Value { + switch name { + case filetype.EdgeFiles: + ids := make([]ent.Value, 0, len(m.removedfiles)) + for id := range m.removedfiles { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *FileTypeMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *FileTypeMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *FileTypeMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown FileType unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *FileTypeMutation) ResetEdge(name string) error { + switch name { + case filetype.EdgeFiles: + m.ResetFiles() + return nil + } + return fmt.Errorf("unknown FileType edge %s", name) +} + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *string + active *bool + expire *time.Time + _type *string + max_users *int + addmax_users *int + name *string + clearedFields map[string]bool + files map[string]struct{} + removedfiles map[string]struct{} + blocked map[string]struct{} + removedblocked map[string]struct{} + users map[string]struct{} + removedusers map[string]struct{} + info *string + clearedinfo bool +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetActive sets the active field. +func (m *GroupMutation) SetActive(b bool) { + m.active = &b +} + +// Active returns the active value in the mutation. +func (m *GroupMutation) Active() (r bool, exists bool) { + v := m.active + if v == nil { + return + } + return *v, true +} + +// ResetActive reset all changes of the active field. +func (m *GroupMutation) ResetActive() { + m.active = nil +} + +// SetExpire sets the expire field. +func (m *GroupMutation) SetExpire(t time.Time) { + m.expire = &t +} + +// Expire returns the expire value in the mutation. +func (m *GroupMutation) Expire() (r time.Time, exists bool) { + v := m.expire + if v == nil { + return + } + return *v, true +} + +// ResetExpire reset all changes of the expire field. +func (m *GroupMutation) ResetExpire() { + m.expire = nil +} + +// SetType sets the type field. +func (m *GroupMutation) SetType(s string) { + m._type = &s +} + +// GetType returns the type value in the mutation. +func (m *GroupMutation) GetType() (r string, exists bool) { + v := m._type + if v == nil { + return + } + return *v, true +} + +// ClearType clears the value of type. +func (m *GroupMutation) ClearType() { + m._type = nil + m.clearedFields[group.FieldType] = true +} + +// TypeCleared returns if the field type was cleared in this mutation. +func (m *GroupMutation) TypeCleared() bool { + return m.clearedFields[group.FieldType] +} + +// ResetType reset all changes of the type field. +func (m *GroupMutation) ResetType() { + m._type = nil + delete(m.clearedFields, group.FieldType) +} + +// SetMaxUsers sets the max_users field. +func (m *GroupMutation) SetMaxUsers(i int) { + m.max_users = &i + m.addmax_users = nil +} + +// MaxUsers returns the max_users value in the mutation. +func (m *GroupMutation) MaxUsers() (r int, exists bool) { + v := m.max_users + if v == nil { + return + } + return *v, true +} + +// AddMaxUsers adds i to max_users. +func (m *GroupMutation) AddMaxUsers(i int) { + if m.addmax_users != nil { + *m.addmax_users += i + } else { + m.addmax_users = &i + } +} + +// AddedMaxUsers returns the value that was added to the max_users field in this mutation. +func (m *GroupMutation) AddedMaxUsers() (r int, exists bool) { + v := m.addmax_users + if v == nil { + return + } + return *v, true +} + +// ClearMaxUsers clears the value of max_users. +func (m *GroupMutation) ClearMaxUsers() { + m.max_users = nil + m.addmax_users = nil + m.clearedFields[group.FieldMaxUsers] = true +} + +// MaxUsersCleared returns if the field max_users was cleared in this mutation. +func (m *GroupMutation) MaxUsersCleared() bool { + return m.clearedFields[group.FieldMaxUsers] +} + +// ResetMaxUsers reset all changes of the max_users field. +func (m *GroupMutation) ResetMaxUsers() { + m.max_users = nil + m.addmax_users = nil + delete(m.clearedFields, group.FieldMaxUsers) +} + +// SetName sets the name field. +func (m *GroupMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *GroupMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *GroupMutation) ResetName() { + m.name = nil +} + +// AddFileIDs adds the files edge to File by ids. +func (m *GroupMutation) AddFileIDs(ids ...string) { + if m.files == nil { + m.files = make(map[string]struct{}) + } + for i := range ids { + m.files[ids[i]] = struct{}{} + } +} + +// RemoveFileIDs removes the files edge to File by ids. +func (m *GroupMutation) RemoveFileIDs(ids ...string) { + if m.removedfiles == nil { + m.removedfiles = make(map[string]struct{}) + } + for i := range ids { + m.removedfiles[ids[i]] = struct{}{} + } +} + +// RemovedFiles returns the removed ids of files. +func (m *GroupMutation) RemovedFilesIDs() (ids []string) { + for id := range m.removedfiles { + ids = append(ids, id) + } + return +} + +// FilesIDs returns the files ids in the mutation. +func (m *GroupMutation) FilesIDs() (ids []string) { + for id := range m.files { + ids = append(ids, id) + } + return +} + +// ResetFiles reset all changes of the files edge. +func (m *GroupMutation) ResetFiles() { + m.files = nil + m.removedfiles = nil +} + +// AddBlockedIDs adds the blocked edge to User by ids. +func (m *GroupMutation) AddBlockedIDs(ids ...string) { + if m.blocked == nil { + m.blocked = make(map[string]struct{}) + } + for i := range ids { + m.blocked[ids[i]] = struct{}{} + } +} + +// RemoveBlockedIDs removes the blocked edge to User by ids. +func (m *GroupMutation) RemoveBlockedIDs(ids ...string) { + if m.removedblocked == nil { + m.removedblocked = make(map[string]struct{}) + } + for i := range ids { + m.removedblocked[ids[i]] = struct{}{} + } +} + +// RemovedBlocked returns the removed ids of blocked. +func (m *GroupMutation) RemovedBlockedIDs() (ids []string) { + for id := range m.removedblocked { + ids = append(ids, id) + } + return +} + +// BlockedIDs returns the blocked ids in the mutation. +func (m *GroupMutation) BlockedIDs() (ids []string) { + for id := range m.blocked { + ids = append(ids, id) + } + return +} + +// ResetBlocked reset all changes of the blocked edge. +func (m *GroupMutation) ResetBlocked() { + m.blocked = nil + m.removedblocked = nil +} + +// AddUserIDs adds the users edge to User by ids. +func (m *GroupMutation) AddUserIDs(ids ...string) { + if m.users == nil { + m.users = make(map[string]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// RemoveUserIDs removes the users edge to User by ids. +func (m *GroupMutation) RemoveUserIDs(ids ...string) { + if m.removedusers == nil { + m.removedusers = make(map[string]struct{}) + } + for i := range ids { + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed ids of users. +func (m *GroupMutation) RemovedUsersIDs() (ids []string) { + for id := range m.removedusers { + ids = append(ids, id) + } + return +} + +// UsersIDs returns the users ids in the mutation. +func (m *GroupMutation) UsersIDs() (ids []string) { + for id := range m.users { + ids = append(ids, id) + } + return +} + +// ResetUsers reset all changes of the users edge. +func (m *GroupMutation) ResetUsers() { + m.users = nil + m.removedusers = nil +} + +// SetInfoID sets the info edge to GroupInfo by id. +func (m *GroupMutation) SetInfoID(id string) { + m.info = &id +} + +// ClearInfo clears the info edge to GroupInfo. +func (m *GroupMutation) ClearInfo() { + m.clearedinfo = true +} + +// InfoCleared returns if the edge info was cleared. +func (m *GroupMutation) InfoCleared() bool { + return m.clearedinfo +} + +// InfoID returns the info id in the mutation. +func (m *GroupMutation) InfoID() (id string, exists bool) { + if m.info != nil { + return *m.info, true + } + return +} + +// InfoIDs returns the info ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// InfoID instead. It exists only for internal usage by the builders. +func (m *GroupMutation) InfoIDs() (ids []string) { + if id := m.info; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetInfo reset all changes of the info edge. +func (m *GroupMutation) ResetInfo() { + m.info = nil + m.clearedinfo = false +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.active != nil { + fields = append(fields, group.FieldActive) + } + if m.expire != nil { + fields = append(fields, group.FieldExpire) + } + if m._type != nil { + fields = append(fields, group.FieldType) + } + if m.max_users != nil { + fields = append(fields, group.FieldMaxUsers) + } + if m.name != nil { + fields = append(fields, group.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + case group.FieldActive: + return m.Active() + case group.FieldExpire: + return m.Expire() + case group.FieldType: + return m.GetType() + case group.FieldMaxUsers: + return m.MaxUsers() + case group.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + case group.FieldActive: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetActive(v) + return nil + case group.FieldExpire: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExpire(v) + return nil + case group.FieldType: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetType(v) + return nil + case group.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMaxUsers(v) + return nil + case group.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + var fields []string + if m.addmax_users != nil { + fields = append(fields, group.FieldMaxUsers) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case group.FieldMaxUsers: + return m.AddedMaxUsers() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + case group.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMaxUsers(v) + return nil + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[group.FieldType] { + fields = append(fields, group.FieldType) + } + if m.clearedFields[group.FieldMaxUsers] { + fields = append(fields, group.FieldMaxUsers) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + switch name { + case group.FieldType: + m.ClearType() + return nil + case group.FieldMaxUsers: + m.ClearMaxUsers() + return nil + } + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + case group.FieldActive: + m.ResetActive() + return nil + case group.FieldExpire: + m.ResetExpire() + return nil + case group.FieldType: + m.ResetType() + return nil + case group.FieldMaxUsers: + m.ResetMaxUsers() + return nil + case group.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 4) + if m.files != nil { + edges = append(edges, group.EdgeFiles) + } + if m.blocked != nil { + edges = append(edges, group.EdgeBlocked) + } + if m.users != nil { + edges = append(edges, group.EdgeUsers) + } + if m.info != nil { + edges = append(edges, group.EdgeInfo) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + case group.EdgeFiles: + ids := make([]ent.Value, 0, len(m.files)) + for id := range m.files { + ids = append(ids, id) + } + return ids + case group.EdgeBlocked: + ids := make([]ent.Value, 0, len(m.blocked)) + for id := range m.blocked { + ids = append(ids, id) + } + return ids + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) + } + return ids + case group.EdgeInfo: + if id := m.info; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 4) + if m.removedfiles != nil { + edges = append(edges, group.EdgeFiles) + } + if m.removedblocked != nil { + edges = append(edges, group.EdgeBlocked) + } + if m.removedusers != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + case group.EdgeFiles: + ids := make([]ent.Value, 0, len(m.removedfiles)) + for id := range m.removedfiles { + ids = append(ids, id) + } + return ids + case group.EdgeBlocked: + ids := make([]ent.Value, 0, len(m.removedblocked)) + for id := range m.removedblocked { + ids = append(ids, id) + } + return ids + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 4) + if m.clearedinfo { + edges = append(edges, group.EdgeInfo) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + case group.EdgeInfo: + return m.clearedinfo + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + switch name { + case group.EdgeInfo: + m.ClearInfo() + return nil + } + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + case group.EdgeFiles: + m.ResetFiles() + return nil + case group.EdgeBlocked: + m.ResetBlocked() + return nil + case group.EdgeUsers: + m.ResetUsers() + return nil + case group.EdgeInfo: + m.ResetInfo() + return nil + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// GroupInfoMutation represents an operation that mutate the GroupInfos +// nodes in the graph. +type GroupInfoMutation struct { + config + op Op + typ string + id *string + desc *string + max_users *int + addmax_users *int + clearedFields map[string]bool + groups map[string]struct{} + removedgroups map[string]struct{} +} + +var _ ent.Mutation = (*GroupInfoMutation)(nil) + +// newGroupInfoMutation creates new mutation for $n.Name. +func newGroupInfoMutation(c config, op Op) *GroupInfoMutation { + return &GroupInfoMutation{ + config: c, + op: op, + typ: TypeGroupInfo, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupInfoMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupInfoMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupInfoMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetDesc sets the desc field. +func (m *GroupInfoMutation) SetDesc(s string) { + m.desc = &s +} + +// Desc returns the desc value in the mutation. +func (m *GroupInfoMutation) Desc() (r string, exists bool) { + v := m.desc + if v == nil { + return + } + return *v, true +} + +// ResetDesc reset all changes of the desc field. +func (m *GroupInfoMutation) ResetDesc() { + m.desc = nil +} + +// SetMaxUsers sets the max_users field. +func (m *GroupInfoMutation) SetMaxUsers(i int) { + m.max_users = &i + m.addmax_users = nil +} + +// MaxUsers returns the max_users value in the mutation. +func (m *GroupInfoMutation) MaxUsers() (r int, exists bool) { + v := m.max_users + if v == nil { + return + } + return *v, true +} + +// AddMaxUsers adds i to max_users. +func (m *GroupInfoMutation) AddMaxUsers(i int) { + if m.addmax_users != nil { + *m.addmax_users += i + } else { + m.addmax_users = &i + } +} + +// AddedMaxUsers returns the value that was added to the max_users field in this mutation. +func (m *GroupInfoMutation) AddedMaxUsers() (r int, exists bool) { + v := m.addmax_users + if v == nil { + return + } + return *v, true +} + +// ResetMaxUsers reset all changes of the max_users field. +func (m *GroupInfoMutation) ResetMaxUsers() { + m.max_users = nil + m.addmax_users = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *GroupInfoMutation) AddGroupIDs(ids ...string) { + if m.groups == nil { + m.groups = make(map[string]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *GroupInfoMutation) RemoveGroupIDs(ids ...string) { + if m.removedgroups == nil { + m.removedgroups = make(map[string]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *GroupInfoMutation) RemovedGroupsIDs() (ids []string) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *GroupInfoMutation) GroupsIDs() (ids []string) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *GroupInfoMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// Op returns the operation name. +func (m *GroupInfoMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (GroupInfo). +func (m *GroupInfoMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupInfoMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.desc != nil { + fields = append(fields, groupinfo.FieldDesc) + } + if m.max_users != nil { + fields = append(fields, groupinfo.FieldMaxUsers) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupInfoMutation) Field(name string) (ent.Value, bool) { + switch name { + case groupinfo.FieldDesc: + return m.Desc() + case groupinfo.FieldMaxUsers: + return m.MaxUsers() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupInfoMutation) SetField(name string, value ent.Value) error { + switch name { + case groupinfo.FieldDesc: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDesc(v) + return nil + case groupinfo.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMaxUsers(v) + return nil + } + return fmt.Errorf("unknown GroupInfo field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupInfoMutation) AddedFields() []string { + var fields []string + if m.addmax_users != nil { + fields = append(fields, groupinfo.FieldMaxUsers) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupInfoMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case groupinfo.FieldMaxUsers: + return m.AddedMaxUsers() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupInfoMutation) AddField(name string, value ent.Value) error { + switch name { + case groupinfo.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMaxUsers(v) + return nil + } + return fmt.Errorf("unknown GroupInfo numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupInfoMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupInfoMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupInfoMutation) ClearField(name string) error { + return fmt.Errorf("unknown GroupInfo nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupInfoMutation) ResetField(name string) error { + switch name { + case groupinfo.FieldDesc: + m.ResetDesc() + return nil + case groupinfo.FieldMaxUsers: + m.ResetMaxUsers() + return nil + } + return fmt.Errorf("unknown GroupInfo field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupInfoMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.groups != nil { + edges = append(edges, groupinfo.EdgeGroups) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupInfoMutation) AddedIDs(name string) []ent.Value { + switch name { + case groupinfo.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupInfoMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedgroups != nil { + edges = append(edges, groupinfo.EdgeGroups) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupInfoMutation) RemovedIDs(name string) []ent.Value { + switch name { + case groupinfo.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupInfoMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupInfoMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupInfoMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown GroupInfo unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupInfoMutation) ResetEdge(name string) error { + switch name { + case groupinfo.EdgeGroups: + m.ResetGroups() + return nil + } + return fmt.Errorf("unknown GroupInfo edge %s", name) +} + +// ItemMutation represents an operation that mutate the Items +// nodes in the graph. +type ItemMutation struct { + config + op Op + typ string + id *string + clearedFields map[string]bool +} + +var _ ent.Mutation = (*ItemMutation)(nil) + +// newItemMutation creates new mutation for $n.Name. +func newItemMutation(c config, op Op) *ItemMutation { + return &ItemMutation{ + config: c, + op: op, + typ: TypeItem, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m ItemMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m ItemMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *ItemMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// Op returns the operation name. +func (m *ItemMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Item). +func (m *ItemMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *ItemMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *ItemMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *ItemMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Item field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *ItemMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *ItemMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *ItemMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Item numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *ItemMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *ItemMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *ItemMutation) ClearField(name string) error { + return fmt.Errorf("unknown Item nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *ItemMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Item field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *ItemMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *ItemMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *ItemMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *ItemMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *ItemMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *ItemMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *ItemMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Item unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *ItemMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Item edge %s", name) +} + +// NodeMutation represents an operation that mutate the Nodes +// nodes in the graph. +type NodeMutation struct { + config + op Op + typ string + id *string + value *int + addvalue *int + clearedFields map[string]bool + prev *string + clearedprev bool + next *string + clearednext bool +} + +var _ ent.Mutation = (*NodeMutation)(nil) + +// newNodeMutation creates new mutation for $n.Name. +func newNodeMutation(c config, op Op) *NodeMutation { + return &NodeMutation{ + config: c, + op: op, + typ: TypeNode, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m NodeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m NodeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *NodeMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetValue sets the value field. +func (m *NodeMutation) SetValue(i int) { + m.value = &i + m.addvalue = nil +} + +// Value returns the value value in the mutation. +func (m *NodeMutation) Value() (r int, exists bool) { + v := m.value + if v == nil { + return + } + return *v, true +} + +// AddValue adds i to value. +func (m *NodeMutation) AddValue(i int) { + if m.addvalue != nil { + *m.addvalue += i + } else { + m.addvalue = &i + } +} + +// AddedValue returns the value that was added to the value field in this mutation. +func (m *NodeMutation) AddedValue() (r int, exists bool) { + v := m.addvalue + if v == nil { + return + } + return *v, true +} + +// ClearValue clears the value of value. +func (m *NodeMutation) ClearValue() { + m.value = nil + m.addvalue = nil + m.clearedFields[node.FieldValue] = true +} + +// ValueCleared returns if the field value was cleared in this mutation. +func (m *NodeMutation) ValueCleared() bool { + return m.clearedFields[node.FieldValue] +} + +// ResetValue reset all changes of the value field. +func (m *NodeMutation) ResetValue() { + m.value = nil + m.addvalue = nil + delete(m.clearedFields, node.FieldValue) +} + +// SetPrevID sets the prev edge to Node by id. +func (m *NodeMutation) SetPrevID(id string) { + m.prev = &id +} + +// ClearPrev clears the prev edge to Node. +func (m *NodeMutation) ClearPrev() { + m.clearedprev = true +} + +// PrevCleared returns if the edge prev was cleared. +func (m *NodeMutation) PrevCleared() bool { + return m.clearedprev +} + +// PrevID returns the prev id in the mutation. +func (m *NodeMutation) PrevID() (id string, exists bool) { + if m.prev != nil { + return *m.prev, true + } + return +} + +// PrevIDs returns the prev ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// PrevID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) PrevIDs() (ids []string) { + if id := m.prev; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetPrev reset all changes of the prev edge. +func (m *NodeMutation) ResetPrev() { + m.prev = nil + m.clearedprev = false +} + +// SetNextID sets the next edge to Node by id. +func (m *NodeMutation) SetNextID(id string) { + m.next = &id +} + +// ClearNext clears the next edge to Node. +func (m *NodeMutation) ClearNext() { + m.clearednext = true +} + +// NextCleared returns if the edge next was cleared. +func (m *NodeMutation) NextCleared() bool { + return m.clearednext +} + +// NextID returns the next id in the mutation. +func (m *NodeMutation) NextID() (id string, exists bool) { + if m.next != nil { + return *m.next, true + } + return +} + +// NextIDs returns the next ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// NextID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) NextIDs() (ids []string) { + if id := m.next; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetNext reset all changes of the next edge. +func (m *NodeMutation) ResetNext() { + m.next = nil + m.clearednext = false +} + +// Op returns the operation name. +func (m *NodeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Node). +func (m *NodeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *NodeMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.value != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *NodeMutation) Field(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.Value() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) SetField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValue(v) + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *NodeMutation) AddedFields() []string { + var fields []string + if m.addvalue != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *NodeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.AddedValue() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) AddField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValue(v) + return nil + } + return fmt.Errorf("unknown Node numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *NodeMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[node.FieldValue] { + fields = append(fields, node.FieldValue) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *NodeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *NodeMutation) ClearField(name string) error { + switch name { + case node.FieldValue: + m.ClearValue() + return nil + } + return fmt.Errorf("unknown Node nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *NodeMutation) ResetField(name string) error { + switch name { + case node.FieldValue: + m.ResetValue() + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *NodeMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.prev != nil { + edges = append(edges, node.EdgePrev) + } + if m.next != nil { + edges = append(edges, node.EdgeNext) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *NodeMutation) AddedIDs(name string) []ent.Value { + switch name { + case node.EdgePrev: + if id := m.prev; id != nil { + return []ent.Value{*id} + } + case node.EdgeNext: + if id := m.next; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *NodeMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *NodeMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *NodeMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedprev { + edges = append(edges, node.EdgePrev) + } + if m.clearednext { + edges = append(edges, node.EdgeNext) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *NodeMutation) EdgeCleared(name string) bool { + switch name { + case node.EdgePrev: + return m.clearedprev + case node.EdgeNext: + return m.clearednext + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *NodeMutation) ClearEdge(name string) error { + switch name { + case node.EdgePrev: + m.ClearPrev() + return nil + case node.EdgeNext: + m.ClearNext() + return nil + } + return fmt.Errorf("unknown Node unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *NodeMutation) ResetEdge(name string) error { + switch name { + case node.EdgePrev: + m.ResetPrev() + return nil + case node.EdgeNext: + m.ResetNext() + return nil + } + return fmt.Errorf("unknown Node edge %s", name) +} + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *string + name *string + clearedFields map[string]bool + team *string + clearedteam bool + owner *string + clearedowner bool +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *PetMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *PetMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *PetMutation) ResetName() { + m.name = nil +} + +// SetTeamID sets the team edge to User by id. +func (m *PetMutation) SetTeamID(id string) { + m.team = &id +} + +// ClearTeam clears the team edge to User. +func (m *PetMutation) ClearTeam() { + m.clearedteam = true +} + +// TeamCleared returns if the edge team was cleared. +func (m *PetMutation) TeamCleared() bool { + return m.clearedteam +} + +// TeamID returns the team id in the mutation. +func (m *PetMutation) TeamID() (id string, exists bool) { + if m.team != nil { + return *m.team, true + } + return +} + +// TeamIDs returns the team ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// TeamID instead. It exists only for internal usage by the builders. +func (m *PetMutation) TeamIDs() (ids []string) { + if id := m.team; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetTeam reset all changes of the team edge. +func (m *PetMutation) ResetTeam() { + m.team = nil + m.clearedteam = false +} + +// SetOwnerID sets the owner edge to User by id. +func (m *PetMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *PetMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *PetMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *PetMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *PetMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *PetMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, pet.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + case pet.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + case pet.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + case pet.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.team != nil { + edges = append(edges, pet.EdgeTeam) + } + if m.owner != nil { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + case pet.EdgeTeam: + if id := m.team; id != nil { + return []ent.Value{*id} + } + case pet.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedteam { + edges = append(edges, pet.EdgeTeam) + } + if m.clearedowner { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + case pet.EdgeTeam: + return m.clearedteam + case pet.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + switch name { + case pet.EdgeTeam: + m.ClearTeam() + return nil + case pet.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + case pet.EdgeTeam: + m.ResetTeam() + return nil + case pet.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// SpecMutation represents an operation that mutate the Specs +// nodes in the graph. +type SpecMutation struct { + config + op Op + typ string + id *string + clearedFields map[string]bool + card map[string]struct{} + removedcard map[string]struct{} +} + +var _ ent.Mutation = (*SpecMutation)(nil) + +// newSpecMutation creates new mutation for $n.Name. +func newSpecMutation(c config, op Op) *SpecMutation { + return &SpecMutation{ + config: c, + op: op, + typ: TypeSpec, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m SpecMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m SpecMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *SpecMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// AddCardIDs adds the card edge to Card by ids. +func (m *SpecMutation) AddCardIDs(ids ...string) { + if m.card == nil { + m.card = make(map[string]struct{}) + } + for i := range ids { + m.card[ids[i]] = struct{}{} + } +} + +// RemoveCardIDs removes the card edge to Card by ids. +func (m *SpecMutation) RemoveCardIDs(ids ...string) { + if m.removedcard == nil { + m.removedcard = make(map[string]struct{}) + } + for i := range ids { + m.removedcard[ids[i]] = struct{}{} + } +} + +// RemovedCard returns the removed ids of card. +func (m *SpecMutation) RemovedCardIDs() (ids []string) { + for id := range m.removedcard { + ids = append(ids, id) + } + return +} + +// CardIDs returns the card ids in the mutation. +func (m *SpecMutation) CardIDs() (ids []string) { + for id := range m.card { + ids = append(ids, id) + } + return +} + +// ResetCard reset all changes of the card edge. +func (m *SpecMutation) ResetCard() { + m.card = nil + m.removedcard = nil +} + +// Op returns the operation name. +func (m *SpecMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Spec). +func (m *SpecMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *SpecMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *SpecMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *SpecMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Spec field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *SpecMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *SpecMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *SpecMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Spec numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *SpecMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *SpecMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *SpecMutation) ClearField(name string) error { + return fmt.Errorf("unknown Spec nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *SpecMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Spec field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *SpecMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.card != nil { + edges = append(edges, spec.EdgeCard) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *SpecMutation) AddedIDs(name string) []ent.Value { + switch name { + case spec.EdgeCard: + ids := make([]ent.Value, 0, len(m.card)) + for id := range m.card { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *SpecMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedcard != nil { + edges = append(edges, spec.EdgeCard) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *SpecMutation) RemovedIDs(name string) []ent.Value { + switch name { + case spec.EdgeCard: + ids := make([]ent.Value, 0, len(m.removedcard)) + for id := range m.removedcard { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *SpecMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *SpecMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *SpecMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Spec unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *SpecMutation) ResetEdge(name string) error { + switch name { + case spec.EdgeCard: + m.ResetCard() + return nil + } + return fmt.Errorf("unknown Spec edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *string + optional_int *int + addoptional_int *int + age *int + addage *int + name *string + last *string + nickname *string + phone *string + password *string + role *user.Role + clearedFields map[string]bool + card *string + clearedcard bool + pets map[string]struct{} + removedpets map[string]struct{} + files map[string]struct{} + removedfiles map[string]struct{} + groups map[string]struct{} + removedgroups map[string]struct{} + friends map[string]struct{} + removedfriends map[string]struct{} + followers map[string]struct{} + removedfollowers map[string]struct{} + following map[string]struct{} + removedfollowing map[string]struct{} + team *string + clearedteam bool + spouse *string + clearedspouse bool + children map[string]struct{} + removedchildren map[string]struct{} + parent *string + clearedparent bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetOptionalInt sets the optional_int field. +func (m *UserMutation) SetOptionalInt(i int) { + m.optional_int = &i + m.addoptional_int = nil +} + +// OptionalInt returns the optional_int value in the mutation. +func (m *UserMutation) OptionalInt() (r int, exists bool) { + v := m.optional_int + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt adds i to optional_int. +func (m *UserMutation) AddOptionalInt(i int) { + if m.addoptional_int != nil { + *m.addoptional_int += i + } else { + m.addoptional_int = &i + } +} + +// AddedOptionalInt returns the value that was added to the optional_int field in this mutation. +func (m *UserMutation) AddedOptionalInt() (r int, exists bool) { + v := m.addoptional_int + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt clears the value of optional_int. +func (m *UserMutation) ClearOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + m.clearedFields[user.FieldOptionalInt] = true +} + +// OptionalIntCleared returns if the field optional_int was cleared in this mutation. +func (m *UserMutation) OptionalIntCleared() bool { + return m.clearedFields[user.FieldOptionalInt] +} + +// ResetOptionalInt reset all changes of the optional_int field. +func (m *UserMutation) ResetOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + delete(m.clearedFields, user.FieldOptionalInt) +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetLast sets the last field. +func (m *UserMutation) SetLast(s string) { + m.last = &s +} + +// Last returns the last value in the mutation. +func (m *UserMutation) Last() (r string, exists bool) { + v := m.last + if v == nil { + return + } + return *v, true +} + +// ResetLast reset all changes of the last field. +func (m *UserMutation) ResetLast() { + m.last = nil +} + +// SetNickname sets the nickname field. +func (m *UserMutation) SetNickname(s string) { + m.nickname = &s +} + +// Nickname returns the nickname value in the mutation. +func (m *UserMutation) Nickname() (r string, exists bool) { + v := m.nickname + if v == nil { + return + } + return *v, true +} + +// ClearNickname clears the value of nickname. +func (m *UserMutation) ClearNickname() { + m.nickname = nil + m.clearedFields[user.FieldNickname] = true +} + +// NicknameCleared returns if the field nickname was cleared in this mutation. +func (m *UserMutation) NicknameCleared() bool { + return m.clearedFields[user.FieldNickname] +} + +// ResetNickname reset all changes of the nickname field. +func (m *UserMutation) ResetNickname() { + m.nickname = nil + delete(m.clearedFields, user.FieldNickname) +} + +// SetPhone sets the phone field. +func (m *UserMutation) SetPhone(s string) { + m.phone = &s +} + +// Phone returns the phone value in the mutation. +func (m *UserMutation) Phone() (r string, exists bool) { + v := m.phone + if v == nil { + return + } + return *v, true +} + +// ClearPhone clears the value of phone. +func (m *UserMutation) ClearPhone() { + m.phone = nil + m.clearedFields[user.FieldPhone] = true +} + +// PhoneCleared returns if the field phone was cleared in this mutation. +func (m *UserMutation) PhoneCleared() bool { + return m.clearedFields[user.FieldPhone] +} + +// ResetPhone reset all changes of the phone field. +func (m *UserMutation) ResetPhone() { + m.phone = nil + delete(m.clearedFields, user.FieldPhone) +} + +// SetPassword sets the password field. +func (m *UserMutation) SetPassword(s string) { + m.password = &s +} + +// Password returns the password value in the mutation. +func (m *UserMutation) Password() (r string, exists bool) { + v := m.password + if v == nil { + return + } + return *v, true +} + +// ClearPassword clears the value of password. +func (m *UserMutation) ClearPassword() { + m.password = nil + m.clearedFields[user.FieldPassword] = true +} + +// PasswordCleared returns if the field password was cleared in this mutation. +func (m *UserMutation) PasswordCleared() bool { + return m.clearedFields[user.FieldPassword] +} + +// ResetPassword reset all changes of the password field. +func (m *UserMutation) ResetPassword() { + m.password = nil + delete(m.clearedFields, user.FieldPassword) +} + +// SetRole sets the role field. +func (m *UserMutation) SetRole(u user.Role) { + m.role = &u +} + +// Role returns the role value in the mutation. +func (m *UserMutation) Role() (r user.Role, exists bool) { + v := m.role + if v == nil { + return + } + return *v, true +} + +// ResetRole reset all changes of the role field. +func (m *UserMutation) ResetRole() { + m.role = nil +} + +// SetCardID sets the card edge to Card by id. +func (m *UserMutation) SetCardID(id string) { + m.card = &id +} + +// ClearCard clears the card edge to Card. +func (m *UserMutation) ClearCard() { + m.clearedcard = true +} + +// CardCleared returns if the edge card was cleared. +func (m *UserMutation) CardCleared() bool { + return m.clearedcard +} + +// CardID returns the card id in the mutation. +func (m *UserMutation) CardID() (id string, exists bool) { + if m.card != nil { + return *m.card, true + } + return +} + +// CardIDs returns the card ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// CardID instead. It exists only for internal usage by the builders. +func (m *UserMutation) CardIDs() (ids []string) { + if id := m.card; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetCard reset all changes of the card edge. +func (m *UserMutation) ResetCard() { + m.card = nil + m.clearedcard = false +} + +// AddPetIDs adds the pets edge to Pet by ids. +func (m *UserMutation) AddPetIDs(ids ...string) { + if m.pets == nil { + m.pets = make(map[string]struct{}) + } + for i := range ids { + m.pets[ids[i]] = struct{}{} + } +} + +// RemovePetIDs removes the pets edge to Pet by ids. +func (m *UserMutation) RemovePetIDs(ids ...string) { + if m.removedpets == nil { + m.removedpets = make(map[string]struct{}) + } + for i := range ids { + m.removedpets[ids[i]] = struct{}{} + } +} + +// RemovedPets returns the removed ids of pets. +func (m *UserMutation) RemovedPetsIDs() (ids []string) { + for id := range m.removedpets { + ids = append(ids, id) + } + return +} + +// PetsIDs returns the pets ids in the mutation. +func (m *UserMutation) PetsIDs() (ids []string) { + for id := range m.pets { + ids = append(ids, id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.removedpets = nil +} + +// AddFileIDs adds the files edge to File by ids. +func (m *UserMutation) AddFileIDs(ids ...string) { + if m.files == nil { + m.files = make(map[string]struct{}) + } + for i := range ids { + m.files[ids[i]] = struct{}{} + } +} + +// RemoveFileIDs removes the files edge to File by ids. +func (m *UserMutation) RemoveFileIDs(ids ...string) { + if m.removedfiles == nil { + m.removedfiles = make(map[string]struct{}) + } + for i := range ids { + m.removedfiles[ids[i]] = struct{}{} + } +} + +// RemovedFiles returns the removed ids of files. +func (m *UserMutation) RemovedFilesIDs() (ids []string) { + for id := range m.removedfiles { + ids = append(ids, id) + } + return +} + +// FilesIDs returns the files ids in the mutation. +func (m *UserMutation) FilesIDs() (ids []string) { + for id := range m.files { + ids = append(ids, id) + } + return +} + +// ResetFiles reset all changes of the files edge. +func (m *UserMutation) ResetFiles() { + m.files = nil + m.removedfiles = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *UserMutation) AddGroupIDs(ids ...string) { + if m.groups == nil { + m.groups = make(map[string]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *UserMutation) RemoveGroupIDs(ids ...string) { + if m.removedgroups == nil { + m.removedgroups = make(map[string]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *UserMutation) RemovedGroupsIDs() (ids []string) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *UserMutation) GroupsIDs() (ids []string) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *UserMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// AddFriendIDs adds the friends edge to User by ids. +func (m *UserMutation) AddFriendIDs(ids ...string) { + if m.friends == nil { + m.friends = make(map[string]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (m *UserMutation) RemoveFriendIDs(ids ...string) { + if m.removedfriends == nil { + m.removedfriends = make(map[string]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *UserMutation) RemovedFriendsIDs() (ids []string) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *UserMutation) FriendsIDs() (ids []string) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *UserMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// AddFollowerIDs adds the followers edge to User by ids. +func (m *UserMutation) AddFollowerIDs(ids ...string) { + if m.followers == nil { + m.followers = make(map[string]struct{}) + } + for i := range ids { + m.followers[ids[i]] = struct{}{} + } +} + +// RemoveFollowerIDs removes the followers edge to User by ids. +func (m *UserMutation) RemoveFollowerIDs(ids ...string) { + if m.removedfollowers == nil { + m.removedfollowers = make(map[string]struct{}) + } + for i := range ids { + m.removedfollowers[ids[i]] = struct{}{} + } +} + +// RemovedFollowers returns the removed ids of followers. +func (m *UserMutation) RemovedFollowersIDs() (ids []string) { + for id := range m.removedfollowers { + ids = append(ids, id) + } + return +} + +// FollowersIDs returns the followers ids in the mutation. +func (m *UserMutation) FollowersIDs() (ids []string) { + for id := range m.followers { + ids = append(ids, id) + } + return +} + +// ResetFollowers reset all changes of the followers edge. +func (m *UserMutation) ResetFollowers() { + m.followers = nil + m.removedfollowers = nil +} + +// AddFollowingIDs adds the following edge to User by ids. +func (m *UserMutation) AddFollowingIDs(ids ...string) { + if m.following == nil { + m.following = make(map[string]struct{}) + } + for i := range ids { + m.following[ids[i]] = struct{}{} + } +} + +// RemoveFollowingIDs removes the following edge to User by ids. +func (m *UserMutation) RemoveFollowingIDs(ids ...string) { + if m.removedfollowing == nil { + m.removedfollowing = make(map[string]struct{}) + } + for i := range ids { + m.removedfollowing[ids[i]] = struct{}{} + } +} + +// RemovedFollowing returns the removed ids of following. +func (m *UserMutation) RemovedFollowingIDs() (ids []string) { + for id := range m.removedfollowing { + ids = append(ids, id) + } + return +} + +// FollowingIDs returns the following ids in the mutation. +func (m *UserMutation) FollowingIDs() (ids []string) { + for id := range m.following { + ids = append(ids, id) + } + return +} + +// ResetFollowing reset all changes of the following edge. +func (m *UserMutation) ResetFollowing() { + m.following = nil + m.removedfollowing = nil +} + +// SetTeamID sets the team edge to Pet by id. +func (m *UserMutation) SetTeamID(id string) { + m.team = &id +} + +// ClearTeam clears the team edge to Pet. +func (m *UserMutation) ClearTeam() { + m.clearedteam = true +} + +// TeamCleared returns if the edge team was cleared. +func (m *UserMutation) TeamCleared() bool { + return m.clearedteam +} + +// TeamID returns the team id in the mutation. +func (m *UserMutation) TeamID() (id string, exists bool) { + if m.team != nil { + return *m.team, true + } + return +} + +// TeamIDs returns the team ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// TeamID instead. It exists only for internal usage by the builders. +func (m *UserMutation) TeamIDs() (ids []string) { + if id := m.team; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetTeam reset all changes of the team edge. +func (m *UserMutation) ResetTeam() { + m.team = nil + m.clearedteam = false +} + +// SetSpouseID sets the spouse edge to User by id. +func (m *UserMutation) SetSpouseID(id string) { + m.spouse = &id +} + +// ClearSpouse clears the spouse edge to User. +func (m *UserMutation) ClearSpouse() { + m.clearedspouse = true +} + +// SpouseCleared returns if the edge spouse was cleared. +func (m *UserMutation) SpouseCleared() bool { + return m.clearedspouse +} + +// SpouseID returns the spouse id in the mutation. +func (m *UserMutation) SpouseID() (id string, exists bool) { + if m.spouse != nil { + return *m.spouse, true + } + return +} + +// SpouseIDs returns the spouse ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// SpouseID instead. It exists only for internal usage by the builders. +func (m *UserMutation) SpouseIDs() (ids []string) { + if id := m.spouse; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSpouse reset all changes of the spouse edge. +func (m *UserMutation) ResetSpouse() { + m.spouse = nil + m.clearedspouse = false +} + +// AddChildIDs adds the children edge to User by ids. +func (m *UserMutation) AddChildIDs(ids ...string) { + if m.children == nil { + m.children = make(map[string]struct{}) + } + for i := range ids { + m.children[ids[i]] = struct{}{} + } +} + +// RemoveChildIDs removes the children edge to User by ids. +func (m *UserMutation) RemoveChildIDs(ids ...string) { + if m.removedchildren == nil { + m.removedchildren = make(map[string]struct{}) + } + for i := range ids { + m.removedchildren[ids[i]] = struct{}{} + } +} + +// RemovedChildren returns the removed ids of children. +func (m *UserMutation) RemovedChildrenIDs() (ids []string) { + for id := range m.removedchildren { + ids = append(ids, id) + } + return +} + +// ChildrenIDs returns the children ids in the mutation. +func (m *UserMutation) ChildrenIDs() (ids []string) { + for id := range m.children { + ids = append(ids, id) + } + return +} + +// ResetChildren reset all changes of the children edge. +func (m *UserMutation) ResetChildren() { + m.children = nil + m.removedchildren = nil +} + +// SetParentID sets the parent edge to User by id. +func (m *UserMutation) SetParentID(id string) { + m.parent = &id +} + +// ClearParent clears the parent edge to User. +func (m *UserMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared returns if the edge parent was cleared. +func (m *UserMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the parent id in the mutation. +func (m *UserMutation) ParentID() (id string, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the parent ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *UserMutation) ParentIDs() (ids []string) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent reset all changes of the parent edge. +func (m *UserMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 8) + if m.optional_int != nil { + fields = append(fields, user.FieldOptionalInt) + } + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + if m.last != nil { + fields = append(fields, user.FieldLast) + } + if m.nickname != nil { + fields = append(fields, user.FieldNickname) + } + if m.phone != nil { + fields = append(fields, user.FieldPhone) + } + if m.password != nil { + fields = append(fields, user.FieldPassword) + } + if m.role != nil { + fields = append(fields, user.FieldRole) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldOptionalInt: + return m.OptionalInt() + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + case user.FieldLast: + return m.Last() + case user.FieldNickname: + return m.Nickname() + case user.FieldPhone: + return m.Phone() + case user.FieldPassword: + return m.Password() + case user.FieldRole: + return m.Role() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt(v) + return nil + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case user.FieldLast: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLast(v) + return nil + case user.FieldNickname: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNickname(v) + return nil + case user.FieldPhone: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPhone(v) + return nil + case user.FieldPassword: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPassword(v) + return nil + case user.FieldRole: + v, ok := value.(user.Role) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRole(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addoptional_int != nil { + fields = append(fields, user.FieldOptionalInt) + } + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldOptionalInt: + return m.AddedOptionalInt() + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt(v) + return nil + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[user.FieldOptionalInt] { + fields = append(fields, user.FieldOptionalInt) + } + if m.clearedFields[user.FieldNickname] { + fields = append(fields, user.FieldNickname) + } + if m.clearedFields[user.FieldPhone] { + fields = append(fields, user.FieldPhone) + } + if m.clearedFields[user.FieldPassword] { + fields = append(fields, user.FieldPassword) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + switch name { + case user.FieldOptionalInt: + m.ClearOptionalInt() + return nil + case user.FieldNickname: + m.ClearNickname() + return nil + case user.FieldPhone: + m.ClearPhone() + return nil + case user.FieldPassword: + m.ClearPassword() + return nil + } + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldOptionalInt: + m.ResetOptionalInt() + return nil + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + case user.FieldLast: + m.ResetLast() + return nil + case user.FieldNickname: + m.ResetNickname() + return nil + case user.FieldPhone: + m.ResetPhone() + return nil + case user.FieldPassword: + m.ResetPassword() + return nil + case user.FieldRole: + m.ResetRole() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 11) + if m.card != nil { + edges = append(edges, user.EdgeCard) + } + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + if m.files != nil { + edges = append(edges, user.EdgeFiles) + } + if m.groups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.friends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.followers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.following != nil { + edges = append(edges, user.EdgeFollowing) + } + if m.team != nil { + edges = append(edges, user.EdgeTeam) + } + if m.spouse != nil { + edges = append(edges, user.EdgeSpouse) + } + if m.children != nil { + edges = append(edges, user.EdgeChildren) + } + if m.parent != nil { + edges = append(edges, user.EdgeParent) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeCard: + if id := m.card; id != nil { + return []ent.Value{*id} + } + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.pets)) + for id := range m.pets { + ids = append(ids, id) + } + return ids + case user.EdgeFiles: + ids := make([]ent.Value, 0, len(m.files)) + for id := range m.files { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.followers)) + for id := range m.followers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.following)) + for id := range m.following { + ids = append(ids, id) + } + return ids + case user.EdgeTeam: + if id := m.team; id != nil { + return []ent.Value{*id} + } + case user.EdgeSpouse: + if id := m.spouse; id != nil { + return []ent.Value{*id} + } + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.children)) + for id := range m.children { + ids = append(ids, id) + } + return ids + case user.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 11) + if m.removedpets != nil { + edges = append(edges, user.EdgePets) + } + if m.removedfiles != nil { + edges = append(edges, user.EdgeFiles) + } + if m.removedgroups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.removedfriends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.removedfollowers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.removedfollowing != nil { + edges = append(edges, user.EdgeFollowing) + } + if m.removedchildren != nil { + edges = append(edges, user.EdgeChildren) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.removedpets)) + for id := range m.removedpets { + ids = append(ids, id) + } + return ids + case user.EdgeFiles: + ids := make([]ent.Value, 0, len(m.removedfiles)) + for id := range m.removedfiles { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.removedfollowers)) + for id := range m.removedfollowers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.removedfollowing)) + for id := range m.removedfollowing { + ids = append(ids, id) + } + return ids + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.removedchildren)) + for id := range m.removedchildren { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 11) + if m.clearedcard { + edges = append(edges, user.EdgeCard) + } + if m.clearedteam { + edges = append(edges, user.EdgeTeam) + } + if m.clearedspouse { + edges = append(edges, user.EdgeSpouse) + } + if m.clearedparent { + edges = append(edges, user.EdgeParent) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeCard: + return m.clearedcard + case user.EdgeTeam: + return m.clearedteam + case user.EdgeSpouse: + return m.clearedspouse + case user.EdgeParent: + return m.clearedparent + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeCard: + m.ClearCard() + return nil + case user.EdgeTeam: + m.ClearTeam() + return nil + case user.EdgeSpouse: + m.ClearSpouse() + return nil + case user.EdgeParent: + m.ClearParent() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeCard: + m.ResetCard() + return nil + case user.EdgePets: + m.ResetPets() + return nil + case user.EdgeFiles: + m.ResetFiles() + return nil + case user.EdgeGroups: + m.ResetGroups() + return nil + case user.EdgeFriends: + m.ResetFriends() + return nil + case user.EdgeFollowers: + m.ResetFollowers() + return nil + case user.EdgeFollowing: + m.ResetFollowing() + return nil + case user.EdgeTeam: + m.ResetTeam() + return nil + case user.EdgeSpouse: + m.ResetSpouse() + return nil + case user.EdgeChildren: + m.ResetChildren() + return nil + case user.EdgeParent: + m.ResetParent() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/ent/node/node.go b/entc/integration/ent/node/node.go index 1b43e0a98..8e88e2e9f 100644 --- a/entc/integration/ent/node/node.go +++ b/entc/integration/ent/node/node.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the node type in the database. Label = "node" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldValue holds the string denoting the value vertex property in the database. + FieldID = "id" // FieldValue holds the string denoting the value vertex property in the database. FieldValue = "value" + // EdgePrev holds the string denoting the prev edge name in mutations. + EdgePrev = "prev" + // EdgeNext holds the string denoting the next edge name in mutations. + EdgeNext = "next" + // Table holds the table name of the node in the database. Table = "nodes" // PrevTable is the table the holds the prev relation/edge. diff --git a/entc/integration/ent/node_create.go b/entc/integration/ent/node_create.go index fcdea1bf0..20fd51ff3 100644 --- a/entc/integration/ent/node_create.go +++ b/entc/integration/ent/node_create.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,14 +19,13 @@ import ( // NodeCreate is the builder for creating a Node entity. type NodeCreate struct { config - value *int - prev map[string]struct{} - next map[string]struct{} + mutation *NodeMutation + hooks []Hook } // SetValue sets the value field. func (nc *NodeCreate) SetValue(i int) *NodeCreate { - nc.value = &i + nc.mutation.SetValue(i) return nc } @@ -40,10 +39,7 @@ func (nc *NodeCreate) SetNillableValue(i *int) *NodeCreate { // SetPrevID sets the prev edge to Node by id. func (nc *NodeCreate) SetPrevID(id string) *NodeCreate { - if nc.prev == nil { - nc.prev = make(map[string]struct{}) - } - nc.prev[id] = struct{}{} + nc.mutation.SetPrevID(id) return nc } @@ -62,10 +58,7 @@ func (nc *NodeCreate) SetPrev(n *Node) *NodeCreate { // SetNextID sets the next edge to Node by id. func (nc *NodeCreate) SetNextID(id string) *NodeCreate { - if nc.next == nil { - nc.next = make(map[string]struct{}) - } - nc.next[id] = struct{}{} + nc.mutation.SetNextID(id) return nc } @@ -84,13 +77,30 @@ func (nc *NodeCreate) SetNext(n *Node) *NodeCreate { // Save creates the Node in the database. func (nc *NodeCreate) Save(ctx context.Context) (*Node, error) { - if len(nc.prev) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"prev\"") + var ( + err error + node *Node + ) + if len(nc.hooks) == 0 { + node, err = nc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nc.mutation = mutation + node, err = nc.sqlSave(ctx) + return node, err + }) + for i := len(nc.hooks); i > 0; i-- { + mut = nc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nc.mutation); err != nil { + return nil, err + } } - if len(nc.next) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -113,15 +123,15 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, } ) - if value := nc.value; value != nil { + if value, ok := nc.mutation.Value(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) - n.Value = *value + n.Value = value } - if nodes := nc.prev; len(nodes) > 0 { + if nodes := nc.mutation.PrevIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -135,7 +145,7 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -144,7 +154,7 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := nc.next; len(nodes) > 0 { + if nodes := nc.mutation.NextIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -158,7 +168,7 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/node_delete.go b/entc/integration/ent/node_delete.go index c09aeee6e..377a604d3 100644 --- a/entc/integration/ent/node_delete.go +++ b/entc/integration/ent/node_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // NodeDelete is the builder for deleting a Node entity. type NodeDelete struct { config + hooks []Hook + mutation *NodeMutation predicates []predicate.Node } @@ -30,7 +33,30 @@ func (nd *NodeDelete) Where(ps ...predicate.Node) *NodeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (nd *NodeDelete) Exec(ctx context.Context) (int, error) { - return nd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(nd.hooks) == 0 { + affected, err = nd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nd.mutation = mutation + affected, err = nd.sqlExec(ctx) + return affected, err + }) + for i := len(nd.hooks); i > 0; i-- { + mut = nd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/node_update.go b/entc/integration/ent/node_update.go index 01468aab4..a573e8dd3 100644 --- a/entc/integration/ent/node_update.go +++ b/entc/integration/ent/node_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql" @@ -21,14 +21,9 @@ import ( // NodeUpdate is the builder for updating Node entities. type NodeUpdate struct { config - value *int - addvalue *int - clearvalue bool - prev map[string]struct{} - next map[string]struct{} - clearedPrev bool - clearedNext bool - predicates []predicate.Node + hooks []Hook + mutation *NodeMutation + predicates []predicate.Node } // Where adds a new predicate for the builder. @@ -39,8 +34,8 @@ func (nu *NodeUpdate) Where(ps ...predicate.Node) *NodeUpdate { // SetValue sets the value field. func (nu *NodeUpdate) SetValue(i int) *NodeUpdate { - nu.value = &i - nu.addvalue = nil + nu.mutation.ResetValue() + nu.mutation.SetValue(i) return nu } @@ -54,27 +49,19 @@ func (nu *NodeUpdate) SetNillableValue(i *int) *NodeUpdate { // AddValue adds i to value. func (nu *NodeUpdate) AddValue(i int) *NodeUpdate { - if nu.addvalue == nil { - nu.addvalue = &i - } else { - *nu.addvalue += i - } + nu.mutation.AddValue(i) return nu } // ClearValue clears the value of value. func (nu *NodeUpdate) ClearValue() *NodeUpdate { - nu.value = nil - nu.clearvalue = true + nu.mutation.ClearValue() return nu } // SetPrevID sets the prev edge to Node by id. func (nu *NodeUpdate) SetPrevID(id string) *NodeUpdate { - if nu.prev == nil { - nu.prev = make(map[string]struct{}) - } - nu.prev[id] = struct{}{} + nu.mutation.SetPrevID(id) return nu } @@ -93,10 +80,7 @@ func (nu *NodeUpdate) SetPrev(n *Node) *NodeUpdate { // SetNextID sets the next edge to Node by id. func (nu *NodeUpdate) SetNextID(id string) *NodeUpdate { - if nu.next == nil { - nu.next = make(map[string]struct{}) - } - nu.next[id] = struct{}{} + nu.mutation.SetNextID(id) return nu } @@ -115,25 +99,43 @@ func (nu *NodeUpdate) SetNext(n *Node) *NodeUpdate { // ClearPrev clears the prev edge to Node. func (nu *NodeUpdate) ClearPrev() *NodeUpdate { - nu.clearedPrev = true + nu.mutation.ClearPrev() return nu } // ClearNext clears the next edge to Node. func (nu *NodeUpdate) ClearNext() *NodeUpdate { - nu.clearedNext = true + nu.mutation.ClearNext() return nu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (nu *NodeUpdate) Save(ctx context.Context) (int, error) { - if len(nu.prev) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"prev\"") + + var ( + err error + affected int + ) + if len(nu.hooks) == 0 { + affected, err = nu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nu.mutation = mutation + affected, err = nu.sqlSave(ctx) + return affected, err + }) + for i := len(nu.hooks); i > 0; i-- { + mut = nu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nu.mutation); err != nil { + return 0, err + } } - if len(nu.next) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -176,27 +178,27 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := nu.value; value != nil { + if value, ok := nu.mutation.Value(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if value := nu.addvalue; value != nil { + if value, ok := nu.mutation.AddedValue(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if nu.clearvalue { + if nu.mutation.ValueCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: node.FieldValue, }) } - if nu.clearedPrev { + if nu.mutation.PrevCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -212,7 +214,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nu.prev; len(nodes) > 0 { + if nodes := nu.mutation.PrevIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -226,7 +228,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -235,7 +237,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nu.clearedNext { + if nu.mutation.NextCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -251,7 +253,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nu.next; len(nodes) > 0 { + if nodes := nu.mutation.NextIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -265,7 +267,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -288,20 +290,14 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { // NodeUpdateOne is the builder for updating a single Node entity. type NodeUpdateOne struct { config - id string - value *int - addvalue *int - clearvalue bool - prev map[string]struct{} - next map[string]struct{} - clearedPrev bool - clearedNext bool + hooks []Hook + mutation *NodeMutation } // SetValue sets the value field. func (nuo *NodeUpdateOne) SetValue(i int) *NodeUpdateOne { - nuo.value = &i - nuo.addvalue = nil + nuo.mutation.ResetValue() + nuo.mutation.SetValue(i) return nuo } @@ -315,27 +311,19 @@ func (nuo *NodeUpdateOne) SetNillableValue(i *int) *NodeUpdateOne { // AddValue adds i to value. func (nuo *NodeUpdateOne) AddValue(i int) *NodeUpdateOne { - if nuo.addvalue == nil { - nuo.addvalue = &i - } else { - *nuo.addvalue += i - } + nuo.mutation.AddValue(i) return nuo } // ClearValue clears the value of value. func (nuo *NodeUpdateOne) ClearValue() *NodeUpdateOne { - nuo.value = nil - nuo.clearvalue = true + nuo.mutation.ClearValue() return nuo } // SetPrevID sets the prev edge to Node by id. func (nuo *NodeUpdateOne) SetPrevID(id string) *NodeUpdateOne { - if nuo.prev == nil { - nuo.prev = make(map[string]struct{}) - } - nuo.prev[id] = struct{}{} + nuo.mutation.SetPrevID(id) return nuo } @@ -354,10 +342,7 @@ func (nuo *NodeUpdateOne) SetPrev(n *Node) *NodeUpdateOne { // SetNextID sets the next edge to Node by id. func (nuo *NodeUpdateOne) SetNextID(id string) *NodeUpdateOne { - if nuo.next == nil { - nuo.next = make(map[string]struct{}) - } - nuo.next[id] = struct{}{} + nuo.mutation.SetNextID(id) return nuo } @@ -376,25 +361,43 @@ func (nuo *NodeUpdateOne) SetNext(n *Node) *NodeUpdateOne { // ClearPrev clears the prev edge to Node. func (nuo *NodeUpdateOne) ClearPrev() *NodeUpdateOne { - nuo.clearedPrev = true + nuo.mutation.ClearPrev() return nuo } // ClearNext clears the next edge to Node. func (nuo *NodeUpdateOne) ClearNext() *NodeUpdateOne { - nuo.clearedNext = true + nuo.mutation.ClearNext() return nuo } // Save executes the query and returns the updated entity. func (nuo *NodeUpdateOne) Save(ctx context.Context) (*Node, error) { - if len(nuo.prev) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"prev\"") + + var ( + err error + node *Node + ) + if len(nuo.hooks) == 0 { + node, err = nuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nuo.mutation = mutation + node, err = nuo.sqlSave(ctx) + return node, err + }) + for i := len(nuo.hooks); i > 0; i-- { + mut = nuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nuo.mutation); err != nil { + return nil, err + } } - if len(nuo.next) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -425,33 +428,37 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { Table: node.Table, Columns: node.Columns, ID: &sqlgraph.FieldSpec{ - Value: nuo.id, Type: field.TypeString, Column: node.FieldID, }, }, } - if value := nuo.value; value != nil { + id, ok := nuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Node.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := nuo.mutation.Value(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if value := nuo.addvalue; value != nil { + if value, ok := nuo.mutation.AddedValue(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if nuo.clearvalue { + if nuo.mutation.ValueCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: node.FieldValue, }) } - if nuo.clearedPrev { + if nuo.mutation.PrevCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -467,7 +474,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nuo.prev; len(nodes) > 0 { + if nodes := nuo.mutation.PrevIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -481,7 +488,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -490,7 +497,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nuo.clearedNext { + if nuo.mutation.NextCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -506,7 +513,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nuo.next; len(nodes) > 0 { + if nodes := nuo.mutation.NextIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -520,7 +527,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/pet/pet.go b/entc/integration/ent/pet/pet.go index 53fa766b0..243153368 100644 --- a/entc/integration/ent/pet/pet.go +++ b/entc/integration/ent/pet/pet.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the pet type in the database. Label = "pet" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeTeam holds the string denoting the team edge name in mutations. + EdgeTeam = "team" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the pet in the database. Table = "pets" // TeamTable is the table the holds the team relation/edge. diff --git a/entc/integration/ent/pet_create.go b/entc/integration/ent/pet_create.go index 565ba29e4..cc6793163 100644 --- a/entc/integration/ent/pet_create.go +++ b/entc/integration/ent/pet_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,23 +21,19 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - name *string - team map[string]struct{} - owner map[string]struct{} + mutation *PetMutation + hooks []Hook } // SetName sets the name field. func (pc *PetCreate) SetName(s string) *PetCreate { - pc.name = &s + pc.mutation.SetName(s) return pc } // SetTeamID sets the team edge to User by id. func (pc *PetCreate) SetTeamID(id string) *PetCreate { - if pc.team == nil { - pc.team = make(map[string]struct{}) - } - pc.team[id] = struct{}{} + pc.mutation.SetTeamID(id) return pc } @@ -55,10 +52,7 @@ func (pc *PetCreate) SetTeam(u *User) *PetCreate { // SetOwnerID sets the owner edge to User by id. func (pc *PetCreate) SetOwnerID(id string) *PetCreate { - if pc.owner == nil { - pc.owner = make(map[string]struct{}) - } - pc.owner[id] = struct{}{} + pc.mutation.SetOwnerID(id) return pc } @@ -77,16 +71,33 @@ func (pc *PetCreate) SetOwner(u *User) *PetCreate { // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - if pc.name == nil { + if _, ok := pc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(pc.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } } - if len(pc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - return pc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -109,15 +120,15 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, } ) - if value := pc.name; value != nil { + if value, ok := pc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) - pe.Name = *value + pe.Name = value } - if nodes := pc.team; len(nodes) > 0 { + if nodes := pc.mutation.TeamIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -131,7 +142,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -140,7 +151,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := pc.owner; len(nodes) > 0 { + if nodes := pc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -154,7 +165,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/pet_delete.go b/entc/integration/ent/pet_delete.go index 5eaafb187..ef11a63da 100644 --- a/entc/integration/ent/pet_delete.go +++ b/entc/integration/ent/pet_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/pet_update.go b/entc/integration/ent/pet_update.go index fbaa38c19..055019150 100644 --- a/entc/integration/ent/pet_update.go +++ b/entc/integration/ent/pet_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql" @@ -22,12 +22,9 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - name *string - team map[string]struct{} - owner map[string]struct{} - clearedTeam bool - clearedOwner bool - predicates []predicate.Pet + hooks []Hook + mutation *PetMutation + predicates []predicate.Pet } // Where adds a new predicate for the builder. @@ -38,16 +35,13 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // SetName sets the name field. func (pu *PetUpdate) SetName(s string) *PetUpdate { - pu.name = &s + pu.mutation.SetName(s) return pu } // SetTeamID sets the team edge to User by id. func (pu *PetUpdate) SetTeamID(id string) *PetUpdate { - if pu.team == nil { - pu.team = make(map[string]struct{}) - } - pu.team[id] = struct{}{} + pu.mutation.SetTeamID(id) return pu } @@ -66,10 +60,7 @@ func (pu *PetUpdate) SetTeam(u *User) *PetUpdate { // SetOwnerID sets the owner edge to User by id. func (pu *PetUpdate) SetOwnerID(id string) *PetUpdate { - if pu.owner == nil { - pu.owner = make(map[string]struct{}) - } - pu.owner[id] = struct{}{} + pu.mutation.SetOwnerID(id) return pu } @@ -88,25 +79,43 @@ func (pu *PetUpdate) SetOwner(u *User) *PetUpdate { // ClearTeam clears the team edge to User. func (pu *PetUpdate) ClearTeam() *PetUpdate { - pu.clearedTeam = true + pu.mutation.ClearTeam() return pu } // ClearOwner clears the owner edge to User. func (pu *PetUpdate) ClearOwner() *PetUpdate { - pu.clearedOwner = true + pu.mutation.ClearOwner() return pu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - if len(pu.team) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"team\"") + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } } - if len(pu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - return pu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -149,14 +158,14 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := pu.name; value != nil { + if value, ok := pu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) } - if pu.clearedTeam { + if pu.mutation.TeamCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -172,7 +181,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.team; len(nodes) > 0 { + if nodes := pu.mutation.TeamIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -186,7 +195,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -195,7 +204,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if pu.clearedOwner { + if pu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -211,7 +220,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.owner; len(nodes) > 0 { + if nodes := pu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -225,7 +234,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -248,26 +257,19 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id string - name *string - team map[string]struct{} - owner map[string]struct{} - clearedTeam bool - clearedOwner bool + hooks []Hook + mutation *PetMutation } // SetName sets the name field. func (puo *PetUpdateOne) SetName(s string) *PetUpdateOne { - puo.name = &s + puo.mutation.SetName(s) return puo } // SetTeamID sets the team edge to User by id. func (puo *PetUpdateOne) SetTeamID(id string) *PetUpdateOne { - if puo.team == nil { - puo.team = make(map[string]struct{}) - } - puo.team[id] = struct{}{} + puo.mutation.SetTeamID(id) return puo } @@ -286,10 +288,7 @@ func (puo *PetUpdateOne) SetTeam(u *User) *PetUpdateOne { // SetOwnerID sets the owner edge to User by id. func (puo *PetUpdateOne) SetOwnerID(id string) *PetUpdateOne { - if puo.owner == nil { - puo.owner = make(map[string]struct{}) - } - puo.owner[id] = struct{}{} + puo.mutation.SetOwnerID(id) return puo } @@ -308,25 +307,43 @@ func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne { // ClearTeam clears the team edge to User. func (puo *PetUpdateOne) ClearTeam() *PetUpdateOne { - puo.clearedTeam = true + puo.mutation.ClearTeam() return puo } // ClearOwner clears the owner edge to User. func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne { - puo.clearedOwner = true + puo.mutation.ClearOwner() return puo } // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - if len(puo.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") + + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } } - if len(puo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - return puo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -357,20 +374,24 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { Table: pet.Table, Columns: pet.Columns, ID: &sqlgraph.FieldSpec{ - Value: puo.id, Type: field.TypeString, Column: pet.FieldID, }, }, } - if value := puo.name; value != nil { + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := puo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) } - if puo.clearedTeam { + if puo.mutation.TeamCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -386,7 +407,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.team; len(nodes) > 0 { + if nodes := puo.mutation.TeamIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -400,7 +421,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -409,7 +430,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if puo.clearedOwner { + if puo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -425,7 +446,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.owner; len(nodes) > 0 { + if nodes := puo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -439,7 +460,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/privacy/privacy.go b/entc/integration/ent/privacy/privacy.go new file mode 100644 index 000000000..b719a2973 --- /dev/null +++ b/entc/integration/ent/privacy/privacy.go @@ -0,0 +1,435 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CardReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CardReadRuleFunc func(context.Context, *ent.Card) error + +// EvalRead calls f(ctx, v). +func (f CardReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Card); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Card", v) +} + +// The CardWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CardWriteRuleFunc func(context.Context, *ent.CardMutation) error + +// EvalWrite calls f(ctx, m). +func (f CardWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CardMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CardMutation", m) +} + +// The CommentReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CommentReadRuleFunc func(context.Context, *ent.Comment) error + +// EvalRead calls f(ctx, v). +func (f CommentReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Comment); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Comment", v) +} + +// The CommentWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CommentWriteRuleFunc func(context.Context, *ent.CommentMutation) error + +// EvalWrite calls f(ctx, m). +func (f CommentWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CommentMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CommentMutation", m) +} + +// The FieldTypeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type FieldTypeReadRuleFunc func(context.Context, *ent.FieldType) error + +// EvalRead calls f(ctx, v). +func (f FieldTypeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.FieldType); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.FieldType", v) +} + +// The FieldTypeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type FieldTypeWriteRuleFunc func(context.Context, *ent.FieldTypeMutation) error + +// EvalWrite calls f(ctx, m). +func (f FieldTypeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.FieldTypeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.FieldTypeMutation", m) +} + +// The FileReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type FileReadRuleFunc func(context.Context, *ent.File) error + +// EvalRead calls f(ctx, v). +func (f FileReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.File); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.File", v) +} + +// The FileWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type FileWriteRuleFunc func(context.Context, *ent.FileMutation) error + +// EvalWrite calls f(ctx, m). +func (f FileWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.FileMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.FileMutation", m) +} + +// The FileTypeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type FileTypeReadRuleFunc func(context.Context, *ent.FileType) error + +// EvalRead calls f(ctx, v). +func (f FileTypeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.FileType); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.FileType", v) +} + +// The FileTypeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type FileTypeWriteRuleFunc func(context.Context, *ent.FileTypeMutation) error + +// EvalWrite calls f(ctx, m). +func (f FileTypeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.FileTypeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.FileTypeMutation", m) +} + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The GroupInfoReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupInfoReadRuleFunc func(context.Context, *ent.GroupInfo) error + +// EvalRead calls f(ctx, v). +func (f GroupInfoReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.GroupInfo); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.GroupInfo", v) +} + +// The GroupInfoWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupInfoWriteRuleFunc func(context.Context, *ent.GroupInfoMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupInfoWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupInfoMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupInfoMutation", m) +} + +// The ItemReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type ItemReadRuleFunc func(context.Context, *ent.Item) error + +// EvalRead calls f(ctx, v). +func (f ItemReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Item); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Item", v) +} + +// The ItemWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type ItemWriteRuleFunc func(context.Context, *ent.ItemMutation) error + +// EvalWrite calls f(ctx, m). +func (f ItemWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.ItemMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.ItemMutation", m) +} + +// The NodeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type NodeReadRuleFunc func(context.Context, *ent.Node) error + +// EvalRead calls f(ctx, v). +func (f NodeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Node); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Node", v) +} + +// The NodeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type NodeWriteRuleFunc func(context.Context, *ent.NodeMutation) error + +// EvalWrite calls f(ctx, m). +func (f NodeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.NodeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.NodeMutation", m) +} + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The SpecReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type SpecReadRuleFunc func(context.Context, *ent.Spec) error + +// EvalRead calls f(ctx, v). +func (f SpecReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Spec); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Spec", v) +} + +// The SpecWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type SpecWriteRuleFunc func(context.Context, *ent.SpecMutation) error + +// EvalWrite calls f(ctx, m). +func (f SpecWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.SpecMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.SpecMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/ent/runtime.go b/entc/integration/ent/runtime.go new file mode 100644 index 000000000..4857d6421 --- /dev/null +++ b/entc/integration/ent/runtime.go @@ -0,0 +1,131 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "time" + + "github.com/facebookincubator/ent/entc/integration/ent/card" + "github.com/facebookincubator/ent/entc/integration/ent/schema" + + "github.com/facebookincubator/ent/entc/integration/ent/fieldtype" + + "github.com/facebookincubator/ent/entc/integration/ent/file" + + "github.com/facebookincubator/ent/entc/integration/ent/group" + + "github.com/facebookincubator/ent/entc/integration/ent/groupinfo" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/entc/integration/ent/user" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + cardMixin := schema.Card{}.Mixin() + cardMixinFields := [...][]ent.Field{ + cardMixin[0].Fields(), + } + cardFields := schema.Card{}.Fields() + // cardDescCreateTime is the schema descriptor for create_time field. + cardDescCreateTime := cardMixinFields[0][0].Descriptor() + // card.DefaultCreateTime holds the default value on creation for the create_time field. + card.DefaultCreateTime = cardDescCreateTime.Default.(func() time.Time) + // cardDescUpdateTime is the schema descriptor for update_time field. + cardDescUpdateTime := cardMixinFields[0][1].Descriptor() + // card.DefaultUpdateTime holds the default value on creation for the update_time field. + card.DefaultUpdateTime = cardDescUpdateTime.Default.(func() time.Time) + // card.UpdateDefaultUpdateTime holds the default value on update for the update_time field. + card.UpdateDefaultUpdateTime = cardDescUpdateTime.UpdateDefault.(func() time.Time) + // cardDescNumber is the schema descriptor for number field. + cardDescNumber := cardFields[0].Descriptor() + // card.NumberValidator is a validator for the "number" field. It is called by the builders before save. + card.NumberValidator = cardDescNumber.Validators[0].(func(string) error) + // cardDescName is the schema descriptor for name field. + cardDescName := cardFields[1].Descriptor() + // card.NameValidator is a validator for the "name" field. It is called by the builders before save. + card.NameValidator = cardDescName.Validators[0].(func(string) error) + fieldtypeFields := schema.FieldType{}.Fields() + // fieldtypeDescValidateOptionalInt32 is the schema descriptor for validate_optional_int32 field. + fieldtypeDescValidateOptionalInt32 := fieldtypeFields[15].Descriptor() + // fieldtype.ValidateOptionalInt32Validator is a validator for the "validate_optional_int32" field. It is called by the builders before save. + fieldtype.ValidateOptionalInt32Validator = fieldtypeDescValidateOptionalInt32.Validators[0].(func(int32) error) + fileFields := schema.File{}.Fields() + // fileDescSize is the schema descriptor for size field. + fileDescSize := fileFields[0].Descriptor() + // file.DefaultSize holds the default value on creation for the size field. + file.DefaultSize = fileDescSize.Default.(int) + // file.SizeValidator is a validator for the "size" field. It is called by the builders before save. + file.SizeValidator = fileDescSize.Validators[0].(func(int) error) + groupFields := schema.Group{}.Fields() + // groupDescActive is the schema descriptor for active field. + groupDescActive := groupFields[0].Descriptor() + // group.DefaultActive holds the default value on creation for the active field. + group.DefaultActive = groupDescActive.Default.(bool) + // groupDescType is the schema descriptor for type field. + groupDescType := groupFields[2].Descriptor() + // group.TypeValidator is a validator for the "type" field. It is called by the builders before save. + group.TypeValidator = func() func(string) error { + validators := groupDescType.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(_type string) error { + for _, fn := range fns { + if err := fn(_type); err != nil { + return err + } + } + return nil + } + }() + // groupDescMaxUsers is the schema descriptor for max_users field. + groupDescMaxUsers := groupFields[3].Descriptor() + // group.DefaultMaxUsers holds the default value on creation for the max_users field. + group.DefaultMaxUsers = groupDescMaxUsers.Default.(int) + // group.MaxUsersValidator is a validator for the "max_users" field. It is called by the builders before save. + group.MaxUsersValidator = groupDescMaxUsers.Validators[0].(func(int) error) + // groupDescName is the schema descriptor for name field. + groupDescName := groupFields[4].Descriptor() + // group.NameValidator is a validator for the "name" field. It is called by the builders before save. + group.NameValidator = func() func(string) error { + validators := groupDescName.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(name string) error { + for _, fn := range fns { + if err := fn(name); err != nil { + return err + } + } + return nil + } + }() + groupinfoFields := schema.GroupInfo{}.Fields() + // groupinfoDescMaxUsers is the schema descriptor for max_users field. + groupinfoDescMaxUsers := groupinfoFields[1].Descriptor() + // groupinfo.DefaultMaxUsers holds the default value on creation for the max_users field. + groupinfo.DefaultMaxUsers = groupinfoDescMaxUsers.Default.(int) + userMixin := schema.User{}.Mixin() + userMixinFields := [...][]ent.Field{ + userMixin[0].Fields(), + } + userFields := schema.User{}.Fields() + // userDescOptionalInt is the schema descriptor for optional_int field. + userDescOptionalInt := userMixinFields[0][0].Descriptor() + // user.OptionalIntValidator is a validator for the "optional_int" field. It is called by the builders before save. + user.OptionalIntValidator = userDescOptionalInt.Validators[0].(func(int) error) + // userDescLast is the schema descriptor for last field. + userDescLast := userFields[2].Descriptor() + // user.DefaultLast holds the default value on creation for the last field. + user.DefaultLast = userDescLast.Default.(string) +} diff --git a/entc/integration/ent/runtime/runtime.go b/entc/integration/ent/runtime/runtime.go new file mode 100644 index 000000000..457327ff6 --- /dev/null +++ b/entc/integration/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/ent/spec/spec.go b/entc/integration/ent/spec/spec.go index ad88e1918..4c313d6d9 100644 --- a/entc/integration/ent/spec/spec.go +++ b/entc/integration/ent/spec/spec.go @@ -12,6 +12,9 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeCard holds the string denoting the card edge name in mutations. + EdgeCard = "card" + // Table holds the table name of the spec in the database. Table = "specs" // CardTable is the table the holds the card relation/edge. The primary key declared below. diff --git a/entc/integration/ent/spec_create.go b/entc/integration/ent/spec_create.go index 9f4a7b5fb..e74c61d1f 100644 --- a/entc/integration/ent/spec_create.go +++ b/entc/integration/ent/spec_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,17 +20,13 @@ import ( // SpecCreate is the builder for creating a Spec entity. type SpecCreate struct { config - card map[string]struct{} + mutation *SpecMutation + hooks []Hook } // AddCardIDs adds the card edge to Card by ids. func (sc *SpecCreate) AddCardIDs(ids ...string) *SpecCreate { - if sc.card == nil { - sc.card = make(map[string]struct{}) - } - for i := range ids { - sc.card[ids[i]] = struct{}{} - } + sc.mutation.AddCardIDs(ids...) return sc } @@ -44,7 +41,30 @@ func (sc *SpecCreate) AddCard(c ...*Card) *SpecCreate { // Save creates the Spec in the database. func (sc *SpecCreate) Save(ctx context.Context) (*Spec, error) { - return sc.sqlSave(ctx) + var ( + err error + node *Spec + ) + if len(sc.hooks) == 0 { + node, err = sc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + sc.mutation = mutation + node, err = sc.sqlSave(ctx) + return node, err + }) + for i := len(sc.hooks); i > 0; i-- { + mut = sc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, sc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -67,7 +87,7 @@ func (sc *SpecCreate) sqlSave(ctx context.Context) (*Spec, error) { }, } ) - if nodes := sc.card; len(nodes) > 0 { + if nodes := sc.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -81,7 +101,7 @@ func (sc *SpecCreate) sqlSave(ctx context.Context) (*Spec, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/spec_delete.go b/entc/integration/ent/spec_delete.go index f7b6d8e2d..28315d9af 100644 --- a/entc/integration/ent/spec_delete.go +++ b/entc/integration/ent/spec_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // SpecDelete is the builder for deleting a Spec entity. type SpecDelete struct { config + hooks []Hook + mutation *SpecMutation predicates []predicate.Spec } @@ -30,7 +33,30 @@ func (sd *SpecDelete) Where(ps ...predicate.Spec) *SpecDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (sd *SpecDelete) Exec(ctx context.Context) (int, error) { - return sd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(sd.hooks) == 0 { + affected, err = sd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + sd.mutation = mutation + affected, err = sd.sqlExec(ctx) + return affected, err + }) + for i := len(sd.hooks); i > 0; i-- { + mut = sd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, sd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/spec_update.go b/entc/integration/ent/spec_update.go index aebe864a5..62f2e1fa3 100644 --- a/entc/integration/ent/spec_update.go +++ b/entc/integration/ent/spec_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "strconv" "github.com/facebookincubator/ent/dialect/sql" @@ -21,9 +22,9 @@ import ( // SpecUpdate is the builder for updating Spec entities. type SpecUpdate struct { config - card map[string]struct{} - removedCard map[string]struct{} - predicates []predicate.Spec + hooks []Hook + mutation *SpecMutation + predicates []predicate.Spec } // Where adds a new predicate for the builder. @@ -34,12 +35,7 @@ func (su *SpecUpdate) Where(ps ...predicate.Spec) *SpecUpdate { // AddCardIDs adds the card edge to Card by ids. func (su *SpecUpdate) AddCardIDs(ids ...string) *SpecUpdate { - if su.card == nil { - su.card = make(map[string]struct{}) - } - for i := range ids { - su.card[ids[i]] = struct{}{} - } + su.mutation.AddCardIDs(ids...) return su } @@ -54,12 +50,7 @@ func (su *SpecUpdate) AddCard(c ...*Card) *SpecUpdate { // RemoveCardIDs removes the card edge to Card by ids. func (su *SpecUpdate) RemoveCardIDs(ids ...string) *SpecUpdate { - if su.removedCard == nil { - su.removedCard = make(map[string]struct{}) - } - for i := range ids { - su.removedCard[ids[i]] = struct{}{} - } + su.mutation.RemoveCardIDs(ids...) return su } @@ -74,7 +65,31 @@ func (su *SpecUpdate) RemoveCard(c ...*Card) *SpecUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (su *SpecUpdate) Save(ctx context.Context) (int, error) { - return su.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(su.hooks) == 0 { + affected, err = su.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + su.mutation = mutation + affected, err = su.sqlSave(ctx) + return affected, err + }) + for i := len(su.hooks); i > 0; i-- { + mut = su.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, su.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -117,7 +132,7 @@ func (su *SpecUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if nodes := su.removedCard; len(nodes) > 0 { + if nodes := su.mutation.RemovedCardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -131,7 +146,7 @@ func (su *SpecUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -140,7 +155,7 @@ func (su *SpecUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := su.card; len(nodes) > 0 { + if nodes := su.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -154,7 +169,7 @@ func (su *SpecUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -177,19 +192,13 @@ func (su *SpecUpdate) sqlSave(ctx context.Context) (n int, err error) { // SpecUpdateOne is the builder for updating a single Spec entity. type SpecUpdateOne struct { config - id string - card map[string]struct{} - removedCard map[string]struct{} + hooks []Hook + mutation *SpecMutation } // AddCardIDs adds the card edge to Card by ids. func (suo *SpecUpdateOne) AddCardIDs(ids ...string) *SpecUpdateOne { - if suo.card == nil { - suo.card = make(map[string]struct{}) - } - for i := range ids { - suo.card[ids[i]] = struct{}{} - } + suo.mutation.AddCardIDs(ids...) return suo } @@ -204,12 +213,7 @@ func (suo *SpecUpdateOne) AddCard(c ...*Card) *SpecUpdateOne { // RemoveCardIDs removes the card edge to Card by ids. func (suo *SpecUpdateOne) RemoveCardIDs(ids ...string) *SpecUpdateOne { - if suo.removedCard == nil { - suo.removedCard = make(map[string]struct{}) - } - for i := range ids { - suo.removedCard[ids[i]] = struct{}{} - } + suo.mutation.RemoveCardIDs(ids...) return suo } @@ -224,7 +228,31 @@ func (suo *SpecUpdateOne) RemoveCard(c ...*Card) *SpecUpdateOne { // Save executes the query and returns the updated entity. func (suo *SpecUpdateOne) Save(ctx context.Context) (*Spec, error) { - return suo.sqlSave(ctx) + + var ( + err error + node *Spec + ) + if len(suo.hooks) == 0 { + node, err = suo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + suo.mutation = mutation + node, err = suo.sqlSave(ctx) + return node, err + }) + for i := len(suo.hooks); i > 0; i-- { + mut = suo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, suo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -255,13 +283,17 @@ func (suo *SpecUpdateOne) sqlSave(ctx context.Context) (s *Spec, err error) { Table: spec.Table, Columns: spec.Columns, ID: &sqlgraph.FieldSpec{ - Value: suo.id, Type: field.TypeString, Column: spec.FieldID, }, }, } - if nodes := suo.removedCard; len(nodes) > 0 { + id, ok := suo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Spec.ID for update") + } + _spec.Node.ID.Value = id + if nodes := suo.mutation.RemovedCardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -275,7 +307,7 @@ func (suo *SpecUpdateOne) sqlSave(ctx context.Context) (s *Spec, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -284,7 +316,7 @@ func (suo *SpecUpdateOne) sqlSave(ctx context.Context) (s *Spec, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := suo.card; len(nodes) > 0 { + if nodes := suo.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -298,7 +330,7 @@ func (suo *SpecUpdateOne) sqlSave(ctx context.Context) (s *Spec, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/tx.go b/entc/integration/ent/tx.go index 98fa528ed..bf9096fd5 100644 --- a/entc/integration/ent/tx.go +++ b/entc/integration/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -54,22 +53,24 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Card: NewCardClient(tx.config), - Comment: NewCommentClient(tx.config), - FieldType: NewFieldTypeClient(tx.config), - File: NewFileClient(tx.config), - FileType: NewFileTypeClient(tx.config), - Group: NewGroupClient(tx.config), - GroupInfo: NewGroupInfoClient(tx.config), - Item: NewItemClient(tx.config), - Node: NewNodeClient(tx.config), - Pet: NewPetClient(tx.config), - Spec: NewSpecClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Card = NewCardClient(tx.config) + tx.Comment = NewCommentClient(tx.config) + tx.FieldType = NewFieldTypeClient(tx.config) + tx.File = NewFileClient(tx.config) + tx.FileType = NewFileTypeClient(tx.config) + tx.Group = NewGroupClient(tx.config) + tx.GroupInfo = NewGroupInfoClient(tx.config) + tx.Item = NewItemClient(tx.config) + tx.Node = NewNodeClient(tx.config) + tx.Pet = NewPetClient(tx.config) + tx.Spec = NewSpecClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/ent/user/user.go b/entc/integration/ent/user/user.go index a0e54eca8..cba06138b 100644 --- a/entc/integration/ent/user/user.go +++ b/entc/integration/ent/user/user.go @@ -8,32 +8,44 @@ package user import ( "fmt" - - "github.com/facebookincubator/ent" - "github.com/facebookincubator/ent/entc/integration/ent/schema" ) const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. - FieldOptionalInt = "optional_int" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" - // FieldLast holds the string denoting the last vertex property in the database. - FieldLast = "last" - // FieldNickname holds the string denoting the nickname vertex property in the database. - FieldNickname = "nickname" - // FieldPhone holds the string denoting the phone vertex property in the database. - FieldPhone = "phone" - // FieldPassword holds the string denoting the password vertex property in the database. - FieldPassword = "password" - // FieldRole holds the string denoting the role vertex property in the database. - FieldRole = "role" + FieldID = "id" // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. + FieldOptionalInt = "optional_int" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldLast holds the string denoting the last vertex property in the database. + FieldLast = "last" // FieldNickname holds the string denoting the nickname vertex property in the database. + FieldNickname = "nickname" // FieldPhone holds the string denoting the phone vertex property in the database. + FieldPhone = "phone" // FieldPassword holds the string denoting the password vertex property in the database. + FieldPassword = "password" // FieldRole holds the string denoting the role vertex property in the database. + FieldRole = "role" + + // EdgeCard holds the string denoting the card edge name in mutations. + EdgeCard = "card" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" + // EdgeFiles holds the string denoting the files edge name in mutations. + EdgeFiles = "files" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // EdgeFollowers holds the string denoting the followers edge name in mutations. + EdgeFollowers = "followers" + // EdgeFollowing holds the string denoting the following edge name in mutations. + EdgeFollowing = "following" + // EdgeTeam holds the string denoting the team edge name in mutations. + EdgeTeam = "team" + // EdgeSpouse holds the string denoting the spouse edge name in mutations. + EdgeSpouse = "spouse" + // EdgeChildren holds the string denoting the children edge name in mutations. + EdgeChildren = "children" + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" // Table holds the table name of the user in the database. Table = "users" @@ -126,21 +138,10 @@ var ( ) var ( - mixin = schema.User{}.Mixin() - mixinFields = [...][]ent.Field{ - mixin[0].Fields(), - } - fields = schema.User{}.Fields() - - // descOptionalInt is the schema descriptor for optional_int field. - descOptionalInt = mixinFields[0][0].Descriptor() // OptionalIntValidator is a validator for the "optional_int" field. It is called by the builders before save. - OptionalIntValidator = descOptionalInt.Validators[0].(func(int) error) - - // descLast is the schema descriptor for last field. - descLast = fields[2].Descriptor() + OptionalIntValidator func(int) error // DefaultLast holds the default value on creation for the last field. - DefaultLast = descLast.Default.(string) + DefaultLast string ) // Role defines the type for the role enum field. diff --git a/entc/integration/ent/user_create.go b/entc/integration/ent/user_create.go index b8f0c8702..5d5241aea 100644 --- a/entc/integration/ent/user_create.go +++ b/entc/integration/ent/user_create.go @@ -24,30 +24,13 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - optional_int *int - age *int - name *string - last *string - nickname *string - phone *string - password *string - role *user.Role - card map[string]struct{} - pets map[string]struct{} - files map[string]struct{} - groups map[string]struct{} - friends map[string]struct{} - followers map[string]struct{} - following map[string]struct{} - team map[string]struct{} - spouse map[string]struct{} - children map[string]struct{} - parent map[string]struct{} + mutation *UserMutation + hooks []Hook } // SetOptionalInt sets the optional_int field. func (uc *UserCreate) SetOptionalInt(i int) *UserCreate { - uc.optional_int = &i + uc.mutation.SetOptionalInt(i) return uc } @@ -61,19 +44,19 @@ func (uc *UserCreate) SetNillableOptionalInt(i *int) *UserCreate { // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetLast sets the last field. func (uc *UserCreate) SetLast(s string) *UserCreate { - uc.last = &s + uc.mutation.SetLast(s) return uc } @@ -87,7 +70,7 @@ func (uc *UserCreate) SetNillableLast(s *string) *UserCreate { // SetNickname sets the nickname field. func (uc *UserCreate) SetNickname(s string) *UserCreate { - uc.nickname = &s + uc.mutation.SetNickname(s) return uc } @@ -101,7 +84,7 @@ func (uc *UserCreate) SetNillableNickname(s *string) *UserCreate { // SetPhone sets the phone field. func (uc *UserCreate) SetPhone(s string) *UserCreate { - uc.phone = &s + uc.mutation.SetPhone(s) return uc } @@ -115,7 +98,7 @@ func (uc *UserCreate) SetNillablePhone(s *string) *UserCreate { // SetPassword sets the password field. func (uc *UserCreate) SetPassword(s string) *UserCreate { - uc.password = &s + uc.mutation.SetPassword(s) return uc } @@ -129,7 +112,7 @@ func (uc *UserCreate) SetNillablePassword(s *string) *UserCreate { // SetRole sets the role field. func (uc *UserCreate) SetRole(u user.Role) *UserCreate { - uc.role = &u + uc.mutation.SetRole(u) return uc } @@ -143,10 +126,7 @@ func (uc *UserCreate) SetNillableRole(u *user.Role) *UserCreate { // SetCardID sets the card edge to Card by id. func (uc *UserCreate) SetCardID(id string) *UserCreate { - if uc.card == nil { - uc.card = make(map[string]struct{}) - } - uc.card[id] = struct{}{} + uc.mutation.SetCardID(id) return uc } @@ -165,12 +145,7 @@ func (uc *UserCreate) SetCard(c *Card) *UserCreate { // AddPetIDs adds the pets edge to Pet by ids. func (uc *UserCreate) AddPetIDs(ids ...string) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[string]struct{}) - } - for i := range ids { - uc.pets[ids[i]] = struct{}{} - } + uc.mutation.AddPetIDs(ids...) return uc } @@ -185,12 +160,7 @@ func (uc *UserCreate) AddPets(p ...*Pet) *UserCreate { // AddFileIDs adds the files edge to File by ids. func (uc *UserCreate) AddFileIDs(ids ...string) *UserCreate { - if uc.files == nil { - uc.files = make(map[string]struct{}) - } - for i := range ids { - uc.files[ids[i]] = struct{}{} - } + uc.mutation.AddFileIDs(ids...) return uc } @@ -205,12 +175,7 @@ func (uc *UserCreate) AddFiles(f ...*File) *UserCreate { // AddGroupIDs adds the groups edge to Group by ids. func (uc *UserCreate) AddGroupIDs(ids ...string) *UserCreate { - if uc.groups == nil { - uc.groups = make(map[string]struct{}) - } - for i := range ids { - uc.groups[ids[i]] = struct{}{} - } + uc.mutation.AddGroupIDs(ids...) return uc } @@ -225,12 +190,7 @@ func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { // AddFriendIDs adds the friends edge to User by ids. func (uc *UserCreate) AddFriendIDs(ids ...string) *UserCreate { - if uc.friends == nil { - uc.friends = make(map[string]struct{}) - } - for i := range ids { - uc.friends[ids[i]] = struct{}{} - } + uc.mutation.AddFriendIDs(ids...) return uc } @@ -245,12 +205,7 @@ func (uc *UserCreate) AddFriends(u ...*User) *UserCreate { // AddFollowerIDs adds the followers edge to User by ids. func (uc *UserCreate) AddFollowerIDs(ids ...string) *UserCreate { - if uc.followers == nil { - uc.followers = make(map[string]struct{}) - } - for i := range ids { - uc.followers[ids[i]] = struct{}{} - } + uc.mutation.AddFollowerIDs(ids...) return uc } @@ -265,12 +220,7 @@ func (uc *UserCreate) AddFollowers(u ...*User) *UserCreate { // AddFollowingIDs adds the following edge to User by ids. func (uc *UserCreate) AddFollowingIDs(ids ...string) *UserCreate { - if uc.following == nil { - uc.following = make(map[string]struct{}) - } - for i := range ids { - uc.following[ids[i]] = struct{}{} - } + uc.mutation.AddFollowingIDs(ids...) return uc } @@ -285,10 +235,7 @@ func (uc *UserCreate) AddFollowing(u ...*User) *UserCreate { // SetTeamID sets the team edge to Pet by id. func (uc *UserCreate) SetTeamID(id string) *UserCreate { - if uc.team == nil { - uc.team = make(map[string]struct{}) - } - uc.team[id] = struct{}{} + uc.mutation.SetTeamID(id) return uc } @@ -307,10 +254,7 @@ func (uc *UserCreate) SetTeam(p *Pet) *UserCreate { // SetSpouseID sets the spouse edge to User by id. func (uc *UserCreate) SetSpouseID(id string) *UserCreate { - if uc.spouse == nil { - uc.spouse = make(map[string]struct{}) - } - uc.spouse[id] = struct{}{} + uc.mutation.SetSpouseID(id) return uc } @@ -329,12 +273,7 @@ func (uc *UserCreate) SetSpouse(u *User) *UserCreate { // AddChildIDs adds the children edge to User by ids. func (uc *UserCreate) AddChildIDs(ids ...string) *UserCreate { - if uc.children == nil { - uc.children = make(map[string]struct{}) - } - for i := range ids { - uc.children[ids[i]] = struct{}{} - } + uc.mutation.AddChildIDs(ids...) return uc } @@ -349,10 +288,7 @@ func (uc *UserCreate) AddChildren(u ...*User) *UserCreate { // SetParentID sets the parent edge to User by id. func (uc *UserCreate) SetParentID(id string) *UserCreate { - if uc.parent == nil { - uc.parent = make(map[string]struct{}) - } - uc.parent[id] = struct{}{} + uc.mutation.SetParentID(id) return uc } @@ -371,41 +307,54 @@ func (uc *UserCreate) SetParent(u *User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.optional_int != nil { - if err := user.OptionalIntValidator(*uc.optional_int); err != nil { + if v, ok := uc.mutation.OptionalInt(); ok { + if err := user.OptionalIntValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"optional_int\": %v", err) } } - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if uc.last == nil { + if _, ok := uc.mutation.Last(); !ok { v := user.DefaultLast - uc.last = &v + uc.mutation.SetLast(v) } - if uc.role == nil { + if _, ok := uc.mutation.Role(); !ok { v := user.DefaultRole - uc.role = &v + uc.mutation.SetRole(v) } - if err := user.RoleValidator(*uc.role); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"role\": %v", err) + if v, ok := uc.mutation.Role(); ok { + if err := user.RoleValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"role\": %v", err) + } } - if len(uc.card) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"card\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - if len(uc.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") - } - if len(uc.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") - } - if len(uc.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") - } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -428,71 +377,71 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.optional_int; value != nil { + if value, ok := uc.mutation.OptionalInt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldOptionalInt, }) - u.OptionalInt = *value + u.OptionalInt = value } - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if value := uc.last; value != nil { + if value, ok := uc.mutation.Last(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldLast, }) - u.Last = *value + u.Last = value } - if value := uc.nickname; value != nil { + if value, ok := uc.mutation.Nickname(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) - u.Nickname = *value + u.Nickname = value } - if value := uc.phone; value != nil { + if value, ok := uc.mutation.Phone(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPhone, }) - u.Phone = *value + u.Phone = value } - if value := uc.password; value != nil { + if value, ok := uc.mutation.Password(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPassword, }) - u.Password = *value + u.Password = value } - if value := uc.role; value != nil { + if value, ok := uc.mutation.Role(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldRole, }) - u.Role = *value + u.Role = value } - if nodes := uc.card; len(nodes) > 0 { + if nodes := uc.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -506,7 +455,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -515,7 +464,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.pets; len(nodes) > 0 { + if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -529,7 +478,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -538,7 +487,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.files; len(nodes) > 0 { + if nodes := uc.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -552,7 +501,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -561,7 +510,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.groups; len(nodes) > 0 { + if nodes := uc.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -575,7 +524,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -584,7 +533,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.friends; len(nodes) > 0 { + if nodes := uc.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -598,7 +547,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -607,7 +556,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.followers; len(nodes) > 0 { + if nodes := uc.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -621,7 +570,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -630,7 +579,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.following; len(nodes) > 0 { + if nodes := uc.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -644,7 +593,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -653,7 +602,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.team; len(nodes) > 0 { + if nodes := uc.mutation.TeamIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -667,7 +616,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -676,7 +625,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.spouse; len(nodes) > 0 { + if nodes := uc.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -690,7 +639,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -699,7 +648,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.children; len(nodes) > 0 { + if nodes := uc.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -713,7 +662,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -722,7 +671,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.parent; len(nodes) > 0 { + if nodes := uc.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -736,7 +685,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/ent/user_delete.go b/entc/integration/ent/user_delete.go index aab0faec4..8379791f4 100644 --- a/entc/integration/ent/user_delete.go +++ b/entc/integration/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/ent/user_update.go b/entc/integration/ent/user_update.go index c0a4b7368..8041f80c2 100644 --- a/entc/integration/ent/user_update.go +++ b/entc/integration/ent/user_update.go @@ -8,7 +8,6 @@ package ent import ( "context" - "errors" "fmt" "strconv" @@ -26,43 +25,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - optional_int *int - addoptional_int *int - clearoptional_int bool - age *int - addage *int - name *string - last *string - nickname *string - clearnickname bool - phone *string - clearphone bool - password *string - clearpassword bool - role *user.Role - card map[string]struct{} - pets map[string]struct{} - files map[string]struct{} - groups map[string]struct{} - friends map[string]struct{} - followers map[string]struct{} - following map[string]struct{} - team map[string]struct{} - spouse map[string]struct{} - children map[string]struct{} - parent map[string]struct{} - clearedCard bool - removedPets map[string]struct{} - removedFiles map[string]struct{} - removedGroups map[string]struct{} - removedFriends map[string]struct{} - removedFollowers map[string]struct{} - removedFollowing map[string]struct{} - clearedTeam bool - clearedSpouse bool - removedChildren map[string]struct{} - clearedParent bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -73,8 +38,8 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetOptionalInt sets the optional_int field. func (uu *UserUpdate) SetOptionalInt(i int) *UserUpdate { - uu.optional_int = &i - uu.addoptional_int = nil + uu.mutation.ResetOptionalInt() + uu.mutation.SetOptionalInt(i) return uu } @@ -88,47 +53,38 @@ func (uu *UserUpdate) SetNillableOptionalInt(i *int) *UserUpdate { // AddOptionalInt adds i to optional_int. func (uu *UserUpdate) AddOptionalInt(i int) *UserUpdate { - if uu.addoptional_int == nil { - uu.addoptional_int = &i - } else { - *uu.addoptional_int += i - } + uu.mutation.AddOptionalInt(i) return uu } // ClearOptionalInt clears the value of optional_int. func (uu *UserUpdate) ClearOptionalInt() *UserUpdate { - uu.optional_int = nil - uu.clearoptional_int = true + uu.mutation.ClearOptionalInt() return uu } // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetLast sets the last field. func (uu *UserUpdate) SetLast(s string) *UserUpdate { - uu.last = &s + uu.mutation.SetLast(s) return uu } @@ -142,7 +98,7 @@ func (uu *UserUpdate) SetNillableLast(s *string) *UserUpdate { // SetNickname sets the nickname field. func (uu *UserUpdate) SetNickname(s string) *UserUpdate { - uu.nickname = &s + uu.mutation.SetNickname(s) return uu } @@ -156,14 +112,13 @@ func (uu *UserUpdate) SetNillableNickname(s *string) *UserUpdate { // ClearNickname clears the value of nickname. func (uu *UserUpdate) ClearNickname() *UserUpdate { - uu.nickname = nil - uu.clearnickname = true + uu.mutation.ClearNickname() return uu } // SetPhone sets the phone field. func (uu *UserUpdate) SetPhone(s string) *UserUpdate { - uu.phone = &s + uu.mutation.SetPhone(s) return uu } @@ -177,14 +132,13 @@ func (uu *UserUpdate) SetNillablePhone(s *string) *UserUpdate { // ClearPhone clears the value of phone. func (uu *UserUpdate) ClearPhone() *UserUpdate { - uu.phone = nil - uu.clearphone = true + uu.mutation.ClearPhone() return uu } // SetPassword sets the password field. func (uu *UserUpdate) SetPassword(s string) *UserUpdate { - uu.password = &s + uu.mutation.SetPassword(s) return uu } @@ -198,14 +152,13 @@ func (uu *UserUpdate) SetNillablePassword(s *string) *UserUpdate { // ClearPassword clears the value of password. func (uu *UserUpdate) ClearPassword() *UserUpdate { - uu.password = nil - uu.clearpassword = true + uu.mutation.ClearPassword() return uu } // SetRole sets the role field. func (uu *UserUpdate) SetRole(u user.Role) *UserUpdate { - uu.role = &u + uu.mutation.SetRole(u) return uu } @@ -219,10 +172,7 @@ func (uu *UserUpdate) SetNillableRole(u *user.Role) *UserUpdate { // SetCardID sets the card edge to Card by id. func (uu *UserUpdate) SetCardID(id string) *UserUpdate { - if uu.card == nil { - uu.card = make(map[string]struct{}) - } - uu.card[id] = struct{}{} + uu.mutation.SetCardID(id) return uu } @@ -241,12 +191,7 @@ func (uu *UserUpdate) SetCard(c *Card) *UserUpdate { // AddPetIDs adds the pets edge to Pet by ids. func (uu *UserUpdate) AddPetIDs(ids ...string) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[string]struct{}) - } - for i := range ids { - uu.pets[ids[i]] = struct{}{} - } + uu.mutation.AddPetIDs(ids...) return uu } @@ -261,12 +206,7 @@ func (uu *UserUpdate) AddPets(p ...*Pet) *UserUpdate { // AddFileIDs adds the files edge to File by ids. func (uu *UserUpdate) AddFileIDs(ids ...string) *UserUpdate { - if uu.files == nil { - uu.files = make(map[string]struct{}) - } - for i := range ids { - uu.files[ids[i]] = struct{}{} - } + uu.mutation.AddFileIDs(ids...) return uu } @@ -281,12 +221,7 @@ func (uu *UserUpdate) AddFiles(f ...*File) *UserUpdate { // AddGroupIDs adds the groups edge to Group by ids. func (uu *UserUpdate) AddGroupIDs(ids ...string) *UserUpdate { - if uu.groups == nil { - uu.groups = make(map[string]struct{}) - } - for i := range ids { - uu.groups[ids[i]] = struct{}{} - } + uu.mutation.AddGroupIDs(ids...) return uu } @@ -301,12 +236,7 @@ func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { // AddFriendIDs adds the friends edge to User by ids. func (uu *UserUpdate) AddFriendIDs(ids ...string) *UserUpdate { - if uu.friends == nil { - uu.friends = make(map[string]struct{}) - } - for i := range ids { - uu.friends[ids[i]] = struct{}{} - } + uu.mutation.AddFriendIDs(ids...) return uu } @@ -321,12 +251,7 @@ func (uu *UserUpdate) AddFriends(u ...*User) *UserUpdate { // AddFollowerIDs adds the followers edge to User by ids. func (uu *UserUpdate) AddFollowerIDs(ids ...string) *UserUpdate { - if uu.followers == nil { - uu.followers = make(map[string]struct{}) - } - for i := range ids { - uu.followers[ids[i]] = struct{}{} - } + uu.mutation.AddFollowerIDs(ids...) return uu } @@ -341,12 +266,7 @@ func (uu *UserUpdate) AddFollowers(u ...*User) *UserUpdate { // AddFollowingIDs adds the following edge to User by ids. func (uu *UserUpdate) AddFollowingIDs(ids ...string) *UserUpdate { - if uu.following == nil { - uu.following = make(map[string]struct{}) - } - for i := range ids { - uu.following[ids[i]] = struct{}{} - } + uu.mutation.AddFollowingIDs(ids...) return uu } @@ -361,10 +281,7 @@ func (uu *UserUpdate) AddFollowing(u ...*User) *UserUpdate { // SetTeamID sets the team edge to Pet by id. func (uu *UserUpdate) SetTeamID(id string) *UserUpdate { - if uu.team == nil { - uu.team = make(map[string]struct{}) - } - uu.team[id] = struct{}{} + uu.mutation.SetTeamID(id) return uu } @@ -383,10 +300,7 @@ func (uu *UserUpdate) SetTeam(p *Pet) *UserUpdate { // SetSpouseID sets the spouse edge to User by id. func (uu *UserUpdate) SetSpouseID(id string) *UserUpdate { - if uu.spouse == nil { - uu.spouse = make(map[string]struct{}) - } - uu.spouse[id] = struct{}{} + uu.mutation.SetSpouseID(id) return uu } @@ -405,12 +319,7 @@ func (uu *UserUpdate) SetSpouse(u *User) *UserUpdate { // AddChildIDs adds the children edge to User by ids. func (uu *UserUpdate) AddChildIDs(ids ...string) *UserUpdate { - if uu.children == nil { - uu.children = make(map[string]struct{}) - } - for i := range ids { - uu.children[ids[i]] = struct{}{} - } + uu.mutation.AddChildIDs(ids...) return uu } @@ -425,10 +334,7 @@ func (uu *UserUpdate) AddChildren(u ...*User) *UserUpdate { // SetParentID sets the parent edge to User by id. func (uu *UserUpdate) SetParentID(id string) *UserUpdate { - if uu.parent == nil { - uu.parent = make(map[string]struct{}) - } - uu.parent[id] = struct{}{} + uu.mutation.SetParentID(id) return uu } @@ -447,18 +353,13 @@ func (uu *UserUpdate) SetParent(u *User) *UserUpdate { // ClearCard clears the card edge to Card. func (uu *UserUpdate) ClearCard() *UserUpdate { - uu.clearedCard = true + uu.mutation.ClearCard() return uu } // RemovePetIDs removes the pets edge to Pet by ids. func (uu *UserUpdate) RemovePetIDs(ids ...string) *UserUpdate { - if uu.removedPets == nil { - uu.removedPets = make(map[string]struct{}) - } - for i := range ids { - uu.removedPets[ids[i]] = struct{}{} - } + uu.mutation.RemovePetIDs(ids...) return uu } @@ -473,12 +374,7 @@ func (uu *UserUpdate) RemovePets(p ...*Pet) *UserUpdate { // RemoveFileIDs removes the files edge to File by ids. func (uu *UserUpdate) RemoveFileIDs(ids ...string) *UserUpdate { - if uu.removedFiles == nil { - uu.removedFiles = make(map[string]struct{}) - } - for i := range ids { - uu.removedFiles[ids[i]] = struct{}{} - } + uu.mutation.RemoveFileIDs(ids...) return uu } @@ -493,12 +389,7 @@ func (uu *UserUpdate) RemoveFiles(f ...*File) *UserUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (uu *UserUpdate) RemoveGroupIDs(ids ...string) *UserUpdate { - if uu.removedGroups == nil { - uu.removedGroups = make(map[string]struct{}) - } - for i := range ids { - uu.removedGroups[ids[i]] = struct{}{} - } + uu.mutation.RemoveGroupIDs(ids...) return uu } @@ -513,12 +404,7 @@ func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { // RemoveFriendIDs removes the friends edge to User by ids. func (uu *UserUpdate) RemoveFriendIDs(ids ...string) *UserUpdate { - if uu.removedFriends == nil { - uu.removedFriends = make(map[string]struct{}) - } - for i := range ids { - uu.removedFriends[ids[i]] = struct{}{} - } + uu.mutation.RemoveFriendIDs(ids...) return uu } @@ -533,12 +419,7 @@ func (uu *UserUpdate) RemoveFriends(u ...*User) *UserUpdate { // RemoveFollowerIDs removes the followers edge to User by ids. func (uu *UserUpdate) RemoveFollowerIDs(ids ...string) *UserUpdate { - if uu.removedFollowers == nil { - uu.removedFollowers = make(map[string]struct{}) - } - for i := range ids { - uu.removedFollowers[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowerIDs(ids...) return uu } @@ -553,12 +434,7 @@ func (uu *UserUpdate) RemoveFollowers(u ...*User) *UserUpdate { // RemoveFollowingIDs removes the following edge to User by ids. func (uu *UserUpdate) RemoveFollowingIDs(ids ...string) *UserUpdate { - if uu.removedFollowing == nil { - uu.removedFollowing = make(map[string]struct{}) - } - for i := range ids { - uu.removedFollowing[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowingIDs(ids...) return uu } @@ -573,24 +449,19 @@ func (uu *UserUpdate) RemoveFollowing(u ...*User) *UserUpdate { // ClearTeam clears the team edge to Pet. func (uu *UserUpdate) ClearTeam() *UserUpdate { - uu.clearedTeam = true + uu.mutation.ClearTeam() return uu } // ClearSpouse clears the spouse edge to User. func (uu *UserUpdate) ClearSpouse() *UserUpdate { - uu.clearedSpouse = true + uu.mutation.ClearSpouse() return uu } // RemoveChildIDs removes the children edge to User by ids. func (uu *UserUpdate) RemoveChildIDs(ids ...string) *UserUpdate { - if uu.removedChildren == nil { - uu.removedChildren = make(map[string]struct{}) - } - for i := range ids { - uu.removedChildren[ids[i]] = struct{}{} - } + uu.mutation.RemoveChildIDs(ids...) return uu } @@ -605,35 +476,47 @@ func (uu *UserUpdate) RemoveChildren(u ...*User) *UserUpdate { // ClearParent clears the parent edge to User. func (uu *UserUpdate) ClearParent() *UserUpdate { - uu.clearedParent = true + uu.mutation.ClearParent() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if uu.optional_int != nil { - if err := user.OptionalIntValidator(*uu.optional_int); err != nil { + if v, ok := uu.mutation.OptionalInt(); ok { + if err := user.OptionalIntValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"optional_int\": %v", err) } } - if uu.role != nil { - if err := user.RoleValidator(*uu.role); err != nil { + if v, ok := uu.mutation.Role(); ok { + if err := user.RoleValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"role\": %v", err) } } - if len(uu.card) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"card\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - if len(uu.team) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"team\"") - } - if len(uu.spouse) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"spouse\"") - } - if len(uu.parent) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"parent\"") - } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -676,101 +559,101 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.optional_int; value != nil { + if value, ok := uu.mutation.OptionalInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldOptionalInt, }) } - if value := uu.addoptional_int; value != nil { + if value, ok := uu.mutation.AddedOptionalInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldOptionalInt, }) } - if uu.clearoptional_int { + if uu.mutation.OptionalIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldOptionalInt, }) } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if value := uu.last; value != nil { + if value, ok := uu.mutation.Last(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldLast, }) } - if value := uu.nickname; value != nil { + if value, ok := uu.mutation.Nickname(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) } - if uu.clearnickname { + if uu.mutation.NicknameCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldNickname, }) } - if value := uu.phone; value != nil { + if value, ok := uu.mutation.Phone(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPhone, }) } - if uu.clearphone { + if uu.mutation.PhoneCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldPhone, }) } - if value := uu.password; value != nil { + if value, ok := uu.mutation.Password(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPassword, }) } - if uu.clearpassword { + if uu.mutation.PasswordCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldPassword, }) } - if value := uu.role; value != nil { + if value, ok := uu.mutation.Role(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldRole, }) } - if uu.clearedCard { + if uu.mutation.CardCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -786,7 +669,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.card; len(nodes) > 0 { + if nodes := uu.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -800,7 +683,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -809,7 +692,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedPets; len(nodes) > 0 { + if nodes := uu.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -823,7 +706,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -832,7 +715,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.pets; len(nodes) > 0 { + if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -846,7 +729,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -855,7 +738,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFiles; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -869,7 +752,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -878,7 +761,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.files; len(nodes) > 0 { + if nodes := uu.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -892,7 +775,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -901,7 +784,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedGroups; len(nodes) > 0 { + if nodes := uu.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -915,7 +798,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -924,7 +807,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.groups; len(nodes) > 0 { + if nodes := uu.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -938,7 +821,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -947,7 +830,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFriends; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -961,7 +844,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -970,7 +853,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.friends; len(nodes) > 0 { + if nodes := uu.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -984,7 +867,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -993,7 +876,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFollowers; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -1007,7 +890,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1016,7 +899,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.followers; len(nodes) > 0 { + if nodes := uu.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -1030,7 +913,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1039,7 +922,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFollowing; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -1053,7 +936,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1062,7 +945,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.following; len(nodes) > 0 { + if nodes := uu.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -1076,7 +959,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1085,7 +968,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedTeam { + if uu.mutation.TeamCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1101,7 +984,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.team; len(nodes) > 0 { + if nodes := uu.mutation.TeamIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1115,7 +998,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1124,7 +1007,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedSpouse { + if uu.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1140,7 +1023,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.spouse; len(nodes) > 0 { + if nodes := uu.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1154,7 +1037,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1163,7 +1046,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedChildren; len(nodes) > 0 { + if nodes := uu.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -1177,7 +1060,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1186,7 +1069,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.children; len(nodes) > 0 { + if nodes := uu.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -1200,7 +1083,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1209,7 +1092,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedParent { + if uu.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -1225,7 +1108,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.parent; len(nodes) > 0 { + if nodes := uu.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -1239,7 +1122,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return 0, err @@ -1262,49 +1145,14 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id string - optional_int *int - addoptional_int *int - clearoptional_int bool - age *int - addage *int - name *string - last *string - nickname *string - clearnickname bool - phone *string - clearphone bool - password *string - clearpassword bool - role *user.Role - card map[string]struct{} - pets map[string]struct{} - files map[string]struct{} - groups map[string]struct{} - friends map[string]struct{} - followers map[string]struct{} - following map[string]struct{} - team map[string]struct{} - spouse map[string]struct{} - children map[string]struct{} - parent map[string]struct{} - clearedCard bool - removedPets map[string]struct{} - removedFiles map[string]struct{} - removedGroups map[string]struct{} - removedFriends map[string]struct{} - removedFollowers map[string]struct{} - removedFollowing map[string]struct{} - clearedTeam bool - clearedSpouse bool - removedChildren map[string]struct{} - clearedParent bool + hooks []Hook + mutation *UserMutation } // SetOptionalInt sets the optional_int field. func (uuo *UserUpdateOne) SetOptionalInt(i int) *UserUpdateOne { - uuo.optional_int = &i - uuo.addoptional_int = nil + uuo.mutation.ResetOptionalInt() + uuo.mutation.SetOptionalInt(i) return uuo } @@ -1318,47 +1166,38 @@ func (uuo *UserUpdateOne) SetNillableOptionalInt(i *int) *UserUpdateOne { // AddOptionalInt adds i to optional_int. func (uuo *UserUpdateOne) AddOptionalInt(i int) *UserUpdateOne { - if uuo.addoptional_int == nil { - uuo.addoptional_int = &i - } else { - *uuo.addoptional_int += i - } + uuo.mutation.AddOptionalInt(i) return uuo } // ClearOptionalInt clears the value of optional_int. func (uuo *UserUpdateOne) ClearOptionalInt() *UserUpdateOne { - uuo.optional_int = nil - uuo.clearoptional_int = true + uuo.mutation.ClearOptionalInt() return uuo } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetLast sets the last field. func (uuo *UserUpdateOne) SetLast(s string) *UserUpdateOne { - uuo.last = &s + uuo.mutation.SetLast(s) return uuo } @@ -1372,7 +1211,7 @@ func (uuo *UserUpdateOne) SetNillableLast(s *string) *UserUpdateOne { // SetNickname sets the nickname field. func (uuo *UserUpdateOne) SetNickname(s string) *UserUpdateOne { - uuo.nickname = &s + uuo.mutation.SetNickname(s) return uuo } @@ -1386,14 +1225,13 @@ func (uuo *UserUpdateOne) SetNillableNickname(s *string) *UserUpdateOne { // ClearNickname clears the value of nickname. func (uuo *UserUpdateOne) ClearNickname() *UserUpdateOne { - uuo.nickname = nil - uuo.clearnickname = true + uuo.mutation.ClearNickname() return uuo } // SetPhone sets the phone field. func (uuo *UserUpdateOne) SetPhone(s string) *UserUpdateOne { - uuo.phone = &s + uuo.mutation.SetPhone(s) return uuo } @@ -1407,14 +1245,13 @@ func (uuo *UserUpdateOne) SetNillablePhone(s *string) *UserUpdateOne { // ClearPhone clears the value of phone. func (uuo *UserUpdateOne) ClearPhone() *UserUpdateOne { - uuo.phone = nil - uuo.clearphone = true + uuo.mutation.ClearPhone() return uuo } // SetPassword sets the password field. func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne { - uuo.password = &s + uuo.mutation.SetPassword(s) return uuo } @@ -1428,14 +1265,13 @@ func (uuo *UserUpdateOne) SetNillablePassword(s *string) *UserUpdateOne { // ClearPassword clears the value of password. func (uuo *UserUpdateOne) ClearPassword() *UserUpdateOne { - uuo.password = nil - uuo.clearpassword = true + uuo.mutation.ClearPassword() return uuo } // SetRole sets the role field. func (uuo *UserUpdateOne) SetRole(u user.Role) *UserUpdateOne { - uuo.role = &u + uuo.mutation.SetRole(u) return uuo } @@ -1449,10 +1285,7 @@ func (uuo *UserUpdateOne) SetNillableRole(u *user.Role) *UserUpdateOne { // SetCardID sets the card edge to Card by id. func (uuo *UserUpdateOne) SetCardID(id string) *UserUpdateOne { - if uuo.card == nil { - uuo.card = make(map[string]struct{}) - } - uuo.card[id] = struct{}{} + uuo.mutation.SetCardID(id) return uuo } @@ -1471,12 +1304,7 @@ func (uuo *UserUpdateOne) SetCard(c *Card) *UserUpdateOne { // AddPetIDs adds the pets edge to Pet by ids. func (uuo *UserUpdateOne) AddPetIDs(ids ...string) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[string]struct{}) - } - for i := range ids { - uuo.pets[ids[i]] = struct{}{} - } + uuo.mutation.AddPetIDs(ids...) return uuo } @@ -1491,12 +1319,7 @@ func (uuo *UserUpdateOne) AddPets(p ...*Pet) *UserUpdateOne { // AddFileIDs adds the files edge to File by ids. func (uuo *UserUpdateOne) AddFileIDs(ids ...string) *UserUpdateOne { - if uuo.files == nil { - uuo.files = make(map[string]struct{}) - } - for i := range ids { - uuo.files[ids[i]] = struct{}{} - } + uuo.mutation.AddFileIDs(ids...) return uuo } @@ -1511,12 +1334,7 @@ func (uuo *UserUpdateOne) AddFiles(f ...*File) *UserUpdateOne { // AddGroupIDs adds the groups edge to Group by ids. func (uuo *UserUpdateOne) AddGroupIDs(ids ...string) *UserUpdateOne { - if uuo.groups == nil { - uuo.groups = make(map[string]struct{}) - } - for i := range ids { - uuo.groups[ids[i]] = struct{}{} - } + uuo.mutation.AddGroupIDs(ids...) return uuo } @@ -1531,12 +1349,7 @@ func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { // AddFriendIDs adds the friends edge to User by ids. func (uuo *UserUpdateOne) AddFriendIDs(ids ...string) *UserUpdateOne { - if uuo.friends == nil { - uuo.friends = make(map[string]struct{}) - } - for i := range ids { - uuo.friends[ids[i]] = struct{}{} - } + uuo.mutation.AddFriendIDs(ids...) return uuo } @@ -1551,12 +1364,7 @@ func (uuo *UserUpdateOne) AddFriends(u ...*User) *UserUpdateOne { // AddFollowerIDs adds the followers edge to User by ids. func (uuo *UserUpdateOne) AddFollowerIDs(ids ...string) *UserUpdateOne { - if uuo.followers == nil { - uuo.followers = make(map[string]struct{}) - } - for i := range ids { - uuo.followers[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowerIDs(ids...) return uuo } @@ -1571,12 +1379,7 @@ func (uuo *UserUpdateOne) AddFollowers(u ...*User) *UserUpdateOne { // AddFollowingIDs adds the following edge to User by ids. func (uuo *UserUpdateOne) AddFollowingIDs(ids ...string) *UserUpdateOne { - if uuo.following == nil { - uuo.following = make(map[string]struct{}) - } - for i := range ids { - uuo.following[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowingIDs(ids...) return uuo } @@ -1591,10 +1394,7 @@ func (uuo *UserUpdateOne) AddFollowing(u ...*User) *UserUpdateOne { // SetTeamID sets the team edge to Pet by id. func (uuo *UserUpdateOne) SetTeamID(id string) *UserUpdateOne { - if uuo.team == nil { - uuo.team = make(map[string]struct{}) - } - uuo.team[id] = struct{}{} + uuo.mutation.SetTeamID(id) return uuo } @@ -1613,10 +1413,7 @@ func (uuo *UserUpdateOne) SetTeam(p *Pet) *UserUpdateOne { // SetSpouseID sets the spouse edge to User by id. func (uuo *UserUpdateOne) SetSpouseID(id string) *UserUpdateOne { - if uuo.spouse == nil { - uuo.spouse = make(map[string]struct{}) - } - uuo.spouse[id] = struct{}{} + uuo.mutation.SetSpouseID(id) return uuo } @@ -1635,12 +1432,7 @@ func (uuo *UserUpdateOne) SetSpouse(u *User) *UserUpdateOne { // AddChildIDs adds the children edge to User by ids. func (uuo *UserUpdateOne) AddChildIDs(ids ...string) *UserUpdateOne { - if uuo.children == nil { - uuo.children = make(map[string]struct{}) - } - for i := range ids { - uuo.children[ids[i]] = struct{}{} - } + uuo.mutation.AddChildIDs(ids...) return uuo } @@ -1655,10 +1447,7 @@ func (uuo *UserUpdateOne) AddChildren(u ...*User) *UserUpdateOne { // SetParentID sets the parent edge to User by id. func (uuo *UserUpdateOne) SetParentID(id string) *UserUpdateOne { - if uuo.parent == nil { - uuo.parent = make(map[string]struct{}) - } - uuo.parent[id] = struct{}{} + uuo.mutation.SetParentID(id) return uuo } @@ -1677,18 +1466,13 @@ func (uuo *UserUpdateOne) SetParent(u *User) *UserUpdateOne { // ClearCard clears the card edge to Card. func (uuo *UserUpdateOne) ClearCard() *UserUpdateOne { - uuo.clearedCard = true + uuo.mutation.ClearCard() return uuo } // RemovePetIDs removes the pets edge to Pet by ids. func (uuo *UserUpdateOne) RemovePetIDs(ids ...string) *UserUpdateOne { - if uuo.removedPets == nil { - uuo.removedPets = make(map[string]struct{}) - } - for i := range ids { - uuo.removedPets[ids[i]] = struct{}{} - } + uuo.mutation.RemovePetIDs(ids...) return uuo } @@ -1703,12 +1487,7 @@ func (uuo *UserUpdateOne) RemovePets(p ...*Pet) *UserUpdateOne { // RemoveFileIDs removes the files edge to File by ids. func (uuo *UserUpdateOne) RemoveFileIDs(ids ...string) *UserUpdateOne { - if uuo.removedFiles == nil { - uuo.removedFiles = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFiles[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFileIDs(ids...) return uuo } @@ -1723,12 +1502,7 @@ func (uuo *UserUpdateOne) RemoveFiles(f ...*File) *UserUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...string) *UserUpdateOne { - if uuo.removedGroups == nil { - uuo.removedGroups = make(map[string]struct{}) - } - for i := range ids { - uuo.removedGroups[ids[i]] = struct{}{} - } + uuo.mutation.RemoveGroupIDs(ids...) return uuo } @@ -1743,12 +1517,7 @@ func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { // RemoveFriendIDs removes the friends edge to User by ids. func (uuo *UserUpdateOne) RemoveFriendIDs(ids ...string) *UserUpdateOne { - if uuo.removedFriends == nil { - uuo.removedFriends = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFriends[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFriendIDs(ids...) return uuo } @@ -1763,12 +1532,7 @@ func (uuo *UserUpdateOne) RemoveFriends(u ...*User) *UserUpdateOne { // RemoveFollowerIDs removes the followers edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowerIDs(ids ...string) *UserUpdateOne { - if uuo.removedFollowers == nil { - uuo.removedFollowers = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFollowers[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowerIDs(ids...) return uuo } @@ -1783,12 +1547,7 @@ func (uuo *UserUpdateOne) RemoveFollowers(u ...*User) *UserUpdateOne { // RemoveFollowingIDs removes the following edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowingIDs(ids ...string) *UserUpdateOne { - if uuo.removedFollowing == nil { - uuo.removedFollowing = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFollowing[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowingIDs(ids...) return uuo } @@ -1803,24 +1562,19 @@ func (uuo *UserUpdateOne) RemoveFollowing(u ...*User) *UserUpdateOne { // ClearTeam clears the team edge to Pet. func (uuo *UserUpdateOne) ClearTeam() *UserUpdateOne { - uuo.clearedTeam = true + uuo.mutation.ClearTeam() return uuo } // ClearSpouse clears the spouse edge to User. func (uuo *UserUpdateOne) ClearSpouse() *UserUpdateOne { - uuo.clearedSpouse = true + uuo.mutation.ClearSpouse() return uuo } // RemoveChildIDs removes the children edge to User by ids. func (uuo *UserUpdateOne) RemoveChildIDs(ids ...string) *UserUpdateOne { - if uuo.removedChildren == nil { - uuo.removedChildren = make(map[string]struct{}) - } - for i := range ids { - uuo.removedChildren[ids[i]] = struct{}{} - } + uuo.mutation.RemoveChildIDs(ids...) return uuo } @@ -1835,35 +1589,47 @@ func (uuo *UserUpdateOne) RemoveChildren(u ...*User) *UserUpdateOne { // ClearParent clears the parent edge to User. func (uuo *UserUpdateOne) ClearParent() *UserUpdateOne { - uuo.clearedParent = true + uuo.mutation.ClearParent() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if uuo.optional_int != nil { - if err := user.OptionalIntValidator(*uuo.optional_int); err != nil { + if v, ok := uuo.mutation.OptionalInt(); ok { + if err := user.OptionalIntValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"optional_int\": %v", err) } } - if uuo.role != nil { - if err := user.RoleValidator(*uuo.role); err != nil { + if v, ok := uuo.mutation.Role(); ok { + if err := user.RoleValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"role\": %v", err) } } - if len(uuo.card) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"card\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - if len(uuo.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") - } - if len(uuo.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") - } - if len(uuo.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") - } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -1894,107 +1660,111 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeString, Column: user.FieldID, }, }, } - if value := uuo.optional_int; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.OptionalInt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldOptionalInt, }) } - if value := uuo.addoptional_int; value != nil { + if value, ok := uuo.mutation.AddedOptionalInt(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldOptionalInt, }) } - if uuo.clearoptional_int { + if uuo.mutation.OptionalIntCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldOptionalInt, }) } - if value := uuo.age; value != nil { + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if value := uuo.last; value != nil { + if value, ok := uuo.mutation.Last(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldLast, }) } - if value := uuo.nickname; value != nil { + if value, ok := uuo.mutation.Nickname(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) } - if uuo.clearnickname { + if uuo.mutation.NicknameCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldNickname, }) } - if value := uuo.phone; value != nil { + if value, ok := uuo.mutation.Phone(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPhone, }) } - if uuo.clearphone { + if uuo.mutation.PhoneCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldPhone, }) } - if value := uuo.password; value != nil { + if value, ok := uuo.mutation.Password(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPassword, }) } - if uuo.clearpassword { + if uuo.mutation.PasswordCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldPassword, }) } - if value := uuo.role; value != nil { + if value, ok := uuo.mutation.Role(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldRole, }) } - if uuo.clearedCard { + if uuo.mutation.CardCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -2010,7 +1780,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.card; len(nodes) > 0 { + if nodes := uuo.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -2024,7 +1794,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2033,7 +1803,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedPets; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -2047,7 +1817,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2056,7 +1826,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.pets; len(nodes) > 0 { + if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -2070,7 +1840,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2079,7 +1849,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFiles; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -2093,7 +1863,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2102,7 +1872,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.files; len(nodes) > 0 { + if nodes := uuo.mutation.FilesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -2116,7 +1886,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2125,7 +1895,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedGroups; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -2139,7 +1909,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2148,7 +1918,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.groups; len(nodes) > 0 { + if nodes := uuo.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -2162,7 +1932,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2171,7 +1941,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFriends; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -2185,7 +1955,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2194,7 +1964,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.friends; len(nodes) > 0 { + if nodes := uuo.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -2208,7 +1978,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2217,7 +1987,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFollowers; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -2231,7 +2001,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2240,7 +2010,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.followers; len(nodes) > 0 { + if nodes := uuo.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -2254,7 +2024,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2263,7 +2033,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFollowing; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -2277,7 +2047,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2286,7 +2056,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.following; len(nodes) > 0 { + if nodes := uuo.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -2300,7 +2070,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2309,7 +2079,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedTeam { + if uuo.mutation.TeamCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -2325,7 +2095,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.team; len(nodes) > 0 { + if nodes := uuo.mutation.TeamIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -2339,7 +2109,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2348,7 +2118,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedSpouse { + if uuo.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -2364,7 +2134,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.spouse; len(nodes) > 0 { + if nodes := uuo.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -2378,7 +2148,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2387,7 +2157,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedChildren; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -2401,7 +2171,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2410,7 +2180,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.children; len(nodes) > 0 { + if nodes := uuo.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -2424,7 +2194,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err @@ -2433,7 +2203,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedParent { + if uuo.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -2449,7 +2219,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.parent; len(nodes) > 0 { + if nodes := uuo.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -2463,7 +2233,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { k, err := strconv.Atoi(k) if err != nil { return nil, err diff --git a/entc/integration/gremlin/ent/card/card.go b/entc/integration/gremlin/ent/card/card.go index 3d2860217..2da0c0ff4 100644 --- a/entc/integration/gremlin/ent/card/card.go +++ b/entc/integration/gremlin/ent/card/card.go @@ -8,24 +8,22 @@ package card import ( "time" - - "github.com/facebookincubator/ent" - "github.com/facebookincubator/ent/entc/integration/ent/schema" ) const ( // Label holds the string label denoting the card type in the database. Label = "card" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldCreateTime holds the string denoting the create_time vertex property in the database. - FieldCreateTime = "create_time" - // FieldUpdateTime holds the string denoting the update_time vertex property in the database. - FieldUpdateTime = "update_time" - // FieldNumber holds the string denoting the number vertex property in the database. - FieldNumber = "number" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" + FieldID = "id" // FieldCreateTime holds the string denoting the create_time vertex property in the database. + FieldCreateTime = "create_time" // FieldUpdateTime holds the string denoting the update_time vertex property in the database. + FieldUpdateTime = "update_time" // FieldNumber holds the string denoting the number vertex property in the database. + FieldNumber = "number" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" + + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // EdgeSpec holds the string denoting the spec edge name in mutations. + EdgeSpec = "spec" // OwnerInverseLabel holds the string label denoting the owner inverse edge type in the database. OwnerInverseLabel = "user_card" @@ -34,31 +32,14 @@ const ( ) var ( - mixin = schema.Card{}.Mixin() - mixinFields = [...][]ent.Field{ - mixin[0].Fields(), - } - fields = schema.Card{}.Fields() - - // descCreateTime is the schema descriptor for create_time field. - descCreateTime = mixinFields[0][0].Descriptor() // DefaultCreateTime holds the default value on creation for the create_time field. - DefaultCreateTime = descCreateTime.Default.(func() time.Time) - - // descUpdateTime is the schema descriptor for update_time field. - descUpdateTime = mixinFields[0][1].Descriptor() + DefaultCreateTime func() time.Time // DefaultUpdateTime holds the default value on creation for the update_time field. - DefaultUpdateTime = descUpdateTime.Default.(func() time.Time) + DefaultUpdateTime func() time.Time // UpdateDefaultUpdateTime holds the default value on update for the update_time field. - UpdateDefaultUpdateTime = descUpdateTime.UpdateDefault.(func() time.Time) - - // descNumber is the schema descriptor for number field. - descNumber = fields[0].Descriptor() + UpdateDefaultUpdateTime func() time.Time // NumberValidator is a validator for the "number" field. It is called by the builders before save. - NumberValidator = descNumber.Validators[0].(func(string) error) - - // descName is the schema descriptor for name field. - descName = fields[1].Descriptor() + NumberValidator func(string) error // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator = descName.Validators[0].(func(string) error) + NameValidator func(string) error ) diff --git a/entc/integration/gremlin/ent/card_create.go b/entc/integration/gremlin/ent/card_create.go index 7667da815..ca1984cfa 100644 --- a/entc/integration/gremlin/ent/card_create.go +++ b/entc/integration/gremlin/ent/card_create.go @@ -25,17 +25,13 @@ import ( // CardCreate is the builder for creating a Card entity. type CardCreate struct { config - create_time *time.Time - update_time *time.Time - number *string - name *string - owner map[string]struct{} - spec map[string]struct{} + mutation *CardMutation + hooks []Hook } // SetCreateTime sets the create_time field. func (cc *CardCreate) SetCreateTime(t time.Time) *CardCreate { - cc.create_time = &t + cc.mutation.SetCreateTime(t) return cc } @@ -49,7 +45,7 @@ func (cc *CardCreate) SetNillableCreateTime(t *time.Time) *CardCreate { // SetUpdateTime sets the update_time field. func (cc *CardCreate) SetUpdateTime(t time.Time) *CardCreate { - cc.update_time = &t + cc.mutation.SetUpdateTime(t) return cc } @@ -63,13 +59,13 @@ func (cc *CardCreate) SetNillableUpdateTime(t *time.Time) *CardCreate { // SetNumber sets the number field. func (cc *CardCreate) SetNumber(s string) *CardCreate { - cc.number = &s + cc.mutation.SetNumber(s) return cc } // SetName sets the name field. func (cc *CardCreate) SetName(s string) *CardCreate { - cc.name = &s + cc.mutation.SetName(s) return cc } @@ -83,10 +79,7 @@ func (cc *CardCreate) SetNillableName(s *string) *CardCreate { // SetOwnerID sets the owner edge to User by id. func (cc *CardCreate) SetOwnerID(id string) *CardCreate { - if cc.owner == nil { - cc.owner = make(map[string]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -105,12 +98,7 @@ func (cc *CardCreate) SetOwner(u *User) *CardCreate { // AddSpecIDs adds the spec edge to Spec by ids. func (cc *CardCreate) AddSpecIDs(ids ...string) *CardCreate { - if cc.spec == nil { - cc.spec = make(map[string]struct{}) - } - for i := range ids { - cc.spec[ids[i]] = struct{}{} - } + cc.mutation.AddSpecIDs(ids...) return cc } @@ -125,29 +113,51 @@ func (cc *CardCreate) AddSpec(s ...*Spec) *CardCreate { // Save creates the Card in the database. func (cc *CardCreate) Save(ctx context.Context) (*Card, error) { - if cc.create_time == nil { + if _, ok := cc.mutation.CreateTime(); !ok { v := card.DefaultCreateTime() - cc.create_time = &v + cc.mutation.SetCreateTime(v) } - if cc.update_time == nil { + if _, ok := cc.mutation.UpdateTime(); !ok { v := card.DefaultUpdateTime() - cc.update_time = &v + cc.mutation.SetUpdateTime(v) } - if cc.number == nil { + if _, ok := cc.mutation.Number(); !ok { return nil, errors.New("ent: missing required field \"number\"") } - if err := card.NumberValidator(*cc.number); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"number\": %v", err) + if v, ok := cc.mutation.Number(); ok { + if err := card.NumberValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"number\": %v", err) + } } - if cc.name != nil { - if err := card.NameValidator(*cc.name); err != nil { + if v, ok := cc.mutation.Name(); ok { + if err := card.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(cc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Card + ) + if len(cc.hooks) == 0 { + node, err = cc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.gremlinSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } } - return cc.gremlinSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -182,26 +192,26 @@ func (cc *CardCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 1) v := g.AddV(card.Label) - if cc.create_time != nil { - v.Property(dsl.Single, card.FieldCreateTime, *cc.create_time) + if value, ok := cc.mutation.CreateTime(); ok { + v.Property(dsl.Single, card.FieldCreateTime, value) } - if cc.update_time != nil { - v.Property(dsl.Single, card.FieldUpdateTime, *cc.update_time) + if value, ok := cc.mutation.UpdateTime(); ok { + v.Property(dsl.Single, card.FieldUpdateTime, value) } - if cc.number != nil { - v.Property(dsl.Single, card.FieldNumber, *cc.number) + if value, ok := cc.mutation.Number(); ok { + v.Property(dsl.Single, card.FieldNumber, value) } - if cc.name != nil { - v.Property(dsl.Single, card.FieldName, *cc.name) + if value, ok := cc.mutation.Name(); ok { + v.Property(dsl.Single, card.FieldName, value) } - for id := range cc.owner { + for _, id := range cc.mutation.OwnerIDs() { v.AddE(user.CardLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.CardLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(card.Label, user.CardLabel, id)), }) } - for id := range cc.spec { + for _, id := range cc.mutation.SpecIDs() { v.AddE(spec.CardLabel).From(g.V(id)).InV() } if len(constraints) == 0 { diff --git a/entc/integration/gremlin/ent/card_delete.go b/entc/integration/gremlin/ent/card_delete.go index f5d4e0679..67b439818 100644 --- a/entc/integration/gremlin/ent/card_delete.go +++ b/entc/integration/gremlin/ent/card_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // CardDelete is the builder for deleting a Card entity. type CardDelete struct { config + hooks []Hook + mutation *CardMutation predicates []predicate.Card } @@ -31,7 +34,30 @@ func (cd *CardDelete) Where(ps ...predicate.Card) *CardDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CardDelete) Exec(ctx context.Context) (int, error) { - return cd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.gremlinExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/card_update.go b/entc/integration/gremlin/ent/card_update.go index e035bc369..7f452c948 100644 --- a/entc/integration/gremlin/ent/card_update.go +++ b/entc/integration/gremlin/ent/card_update.go @@ -8,9 +8,7 @@ package ent import ( "context" - "errors" "fmt" - "time" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -26,16 +24,9 @@ import ( // CardUpdate is the builder for updating Card entities. type CardUpdate struct { config - - update_time *time.Time - - name *string - clearname bool - owner map[string]struct{} - spec map[string]struct{} - clearedOwner bool - removedSpec map[string]struct{} - predicates []predicate.Card + hooks []Hook + mutation *CardMutation + predicates []predicate.Card } // Where adds a new predicate for the builder. @@ -46,7 +37,7 @@ func (cu *CardUpdate) Where(ps ...predicate.Card) *CardUpdate { // SetName sets the name field. func (cu *CardUpdate) SetName(s string) *CardUpdate { - cu.name = &s + cu.mutation.SetName(s) return cu } @@ -60,17 +51,13 @@ func (cu *CardUpdate) SetNillableName(s *string) *CardUpdate { // ClearName clears the value of name. func (cu *CardUpdate) ClearName() *CardUpdate { - cu.name = nil - cu.clearname = true + cu.mutation.ClearName() return cu } // SetOwnerID sets the owner edge to User by id. func (cu *CardUpdate) SetOwnerID(id string) *CardUpdate { - if cu.owner == nil { - cu.owner = make(map[string]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -89,12 +76,7 @@ func (cu *CardUpdate) SetOwner(u *User) *CardUpdate { // AddSpecIDs adds the spec edge to Spec by ids. func (cu *CardUpdate) AddSpecIDs(ids ...string) *CardUpdate { - if cu.spec == nil { - cu.spec = make(map[string]struct{}) - } - for i := range ids { - cu.spec[ids[i]] = struct{}{} - } + cu.mutation.AddSpecIDs(ids...) return cu } @@ -109,18 +91,13 @@ func (cu *CardUpdate) AddSpec(s ...*Spec) *CardUpdate { // ClearOwner clears the owner edge to User. func (cu *CardUpdate) ClearOwner() *CardUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // RemoveSpecIDs removes the spec edge to Spec by ids. func (cu *CardUpdate) RemoveSpecIDs(ids ...string) *CardUpdate { - if cu.removedSpec == nil { - cu.removedSpec = make(map[string]struct{}) - } - for i := range ids { - cu.removedSpec[ids[i]] = struct{}{} - } + cu.mutation.RemoveSpecIDs(ids...) return cu } @@ -135,19 +112,40 @@ func (cu *CardUpdate) RemoveSpec(s ...*Spec) *CardUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CardUpdate) Save(ctx context.Context) (int, error) { - if cu.update_time == nil { + if _, ok := cu.mutation.UpdateTime(); !ok { v := card.UpdateDefaultUpdateTime() - cu.update_time = &v + cu.mutation.SetUpdateTime(v) } - if cu.name != nil { - if err := card.NameValidator(*cu.name); err != nil { + if v, ok := cu.mutation.Name(); ok { + if err := card.NameValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(cu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.gremlinSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } } - return cu.gremlinSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -200,35 +198,35 @@ func (cu *CardUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := cu.update_time; value != nil { - v.Property(dsl.Single, card.FieldUpdateTime, *value) + if value, ok := cu.mutation.UpdateTime(); ok { + v.Property(dsl.Single, card.FieldUpdateTime, value) } - if value := cu.name; value != nil { - v.Property(dsl.Single, card.FieldName, *value) + if value, ok := cu.mutation.Name(); ok { + v.Property(dsl.Single, card.FieldName, value) } var properties []interface{} - if cu.clearname { + if cu.mutation.NameCleared() { properties = append(properties, card.FieldName) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { tr := rv.Clone().InE(user.CardLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range cu.owner { + for _, id := range cu.mutation.OwnerIDs() { v.AddE(user.CardLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.CardLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(card.Label, user.CardLabel, id)), }) } - for id := range cu.removedSpec { + for _, id := range cu.mutation.RemovedSpecIDs() { tr := rv.Clone().InE(spec.CardLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range cu.spec { + for _, id := range cu.mutation.SpecIDs() { v.AddE(spec.CardLabel).From(g.V(id)).InV() } v.Count() @@ -249,21 +247,13 @@ func (cu *CardUpdate) gremlin() *dsl.Traversal { // CardUpdateOne is the builder for updating a single Card entity. type CardUpdateOne struct { config - id string - - update_time *time.Time - - name *string - clearname bool - owner map[string]struct{} - spec map[string]struct{} - clearedOwner bool - removedSpec map[string]struct{} + hooks []Hook + mutation *CardMutation } // SetName sets the name field. func (cuo *CardUpdateOne) SetName(s string) *CardUpdateOne { - cuo.name = &s + cuo.mutation.SetName(s) return cuo } @@ -277,17 +267,13 @@ func (cuo *CardUpdateOne) SetNillableName(s *string) *CardUpdateOne { // ClearName clears the value of name. func (cuo *CardUpdateOne) ClearName() *CardUpdateOne { - cuo.name = nil - cuo.clearname = true + cuo.mutation.ClearName() return cuo } // SetOwnerID sets the owner edge to User by id. func (cuo *CardUpdateOne) SetOwnerID(id string) *CardUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[string]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -306,12 +292,7 @@ func (cuo *CardUpdateOne) SetOwner(u *User) *CardUpdateOne { // AddSpecIDs adds the spec edge to Spec by ids. func (cuo *CardUpdateOne) AddSpecIDs(ids ...string) *CardUpdateOne { - if cuo.spec == nil { - cuo.spec = make(map[string]struct{}) - } - for i := range ids { - cuo.spec[ids[i]] = struct{}{} - } + cuo.mutation.AddSpecIDs(ids...) return cuo } @@ -326,18 +307,13 @@ func (cuo *CardUpdateOne) AddSpec(s ...*Spec) *CardUpdateOne { // ClearOwner clears the owner edge to User. func (cuo *CardUpdateOne) ClearOwner() *CardUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // RemoveSpecIDs removes the spec edge to Spec by ids. func (cuo *CardUpdateOne) RemoveSpecIDs(ids ...string) *CardUpdateOne { - if cuo.removedSpec == nil { - cuo.removedSpec = make(map[string]struct{}) - } - for i := range ids { - cuo.removedSpec[ids[i]] = struct{}{} - } + cuo.mutation.RemoveSpecIDs(ids...) return cuo } @@ -352,19 +328,40 @@ func (cuo *CardUpdateOne) RemoveSpec(s ...*Spec) *CardUpdateOne { // Save executes the query and returns the updated entity. func (cuo *CardUpdateOne) Save(ctx context.Context) (*Card, error) { - if cuo.update_time == nil { + if _, ok := cuo.mutation.UpdateTime(); !ok { v := card.UpdateDefaultUpdateTime() - cuo.update_time = &v + cuo.mutation.SetUpdateTime(v) } - if cuo.name != nil { - if err := card.NameValidator(*cuo.name); err != nil { + if v, ok := cuo.mutation.Name(); ok { + if err := card.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(cuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Card + ) + if len(cuo.hooks) == 0 { + node, err = cuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.gremlinSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } } - return cuo.gremlinSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -391,7 +388,11 @@ func (cuo *CardUpdateOne) ExecX(ctx context.Context) { func (cuo *CardUpdateOne) gremlinSave(ctx context.Context) (*Card, error) { res := &gremlin.Response{} - query, bindings := cuo.gremlin(cuo.id).Query() + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Card.ID for update") + } + query, bindings := cuo.gremlin(id).Query() if err := cuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -418,35 +419,35 @@ func (cuo *CardUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := cuo.update_time; value != nil { - v.Property(dsl.Single, card.FieldUpdateTime, *value) + if value, ok := cuo.mutation.UpdateTime(); ok { + v.Property(dsl.Single, card.FieldUpdateTime, value) } - if value := cuo.name; value != nil { - v.Property(dsl.Single, card.FieldName, *value) + if value, ok := cuo.mutation.Name(); ok { + v.Property(dsl.Single, card.FieldName, value) } var properties []interface{} - if cuo.clearname { + if cuo.mutation.NameCleared() { properties = append(properties, card.FieldName) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if cuo.clearedOwner { + if cuo.mutation.OwnerCleared() { tr := rv.Clone().InE(user.CardLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range cuo.owner { + for _, id := range cuo.mutation.OwnerIDs() { v.AddE(user.CardLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.CardLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(card.Label, user.CardLabel, id)), }) } - for id := range cuo.removedSpec { + for _, id := range cuo.mutation.RemovedSpecIDs() { tr := rv.Clone().InE(spec.CardLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range cuo.spec { + for _, id := range cuo.mutation.SpecIDs() { v.AddE(spec.CardLabel).From(g.V(id)).InV() } v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/client.go b/entc/integration/gremlin/ent/client.go index c1ff21e9e..1271951ee 100644 --- a/entc/integration/gremlin/ent/client.go +++ b/entc/integration/gremlin/ent/client.go @@ -61,23 +61,26 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Card: NewCardClient(c), - Comment: NewCommentClient(c), - FieldType: NewFieldTypeClient(c), - File: NewFileClient(c), - FileType: NewFileTypeClient(c), - Group: NewGroupClient(c), - GroupInfo: NewGroupInfoClient(c), - Item: NewItemClient(c), - Node: NewNodeClient(c), - Pet: NewPetClient(c), - Spec: NewSpecClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Card = NewCardClient(c.config) + c.Comment = NewCommentClient(c.config) + c.FieldType = NewFieldTypeClient(c.config) + c.File = NewFileClient(c.config) + c.FileType = NewFileTypeClient(c.config) + c.Group = NewGroupClient(c.config) + c.GroupInfo = NewGroupInfoClient(c.config) + c.Item = NewItemClient(c.config) + c.Node = NewNodeClient(c.config) + c.Pet = NewPetClient(c.config) + c.Spec = NewSpecClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -114,7 +117,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Card: NewCardClient(cfg), @@ -143,22 +146,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Card: NewCardClient(cfg), - Comment: NewCommentClient(cfg), - FieldType: NewFieldTypeClient(cfg), - File: NewFileClient(cfg), - FileType: NewFileTypeClient(cfg), - Group: NewGroupClient(cfg), - GroupInfo: NewGroupInfoClient(cfg), - Item: NewItemClient(cfg), - Node: NewNodeClient(cfg), - Pet: NewPetClient(cfg), - Spec: NewSpecClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -166,6 +157,23 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Card.Use(hooks...) + c.Comment.Use(hooks...) + c.FieldType.Use(hooks...) + c.File.Use(hooks...) + c.FileType.Use(hooks...) + c.Group.Use(hooks...) + c.GroupInfo.Use(hooks...) + c.Item.Use(hooks...) + c.Node.Use(hooks...) + c.Pet.Use(hooks...) + c.Spec.Use(hooks...) + c.User.Use(hooks...) +} + // CardClient is a client for the Card schema. type CardClient struct { config @@ -176,14 +184,22 @@ func NewCardClient(c config) *CardClient { return &CardClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `card.Hooks(f(g(h())))`. +func (c *CardClient) Use(hooks ...Hook) { + c.hooks.Card = append(c.hooks.Card, hooks...) +} + // Create returns a create builder for Card. func (c *CardClient) Create() *CardCreate { - return &CardCreate{config: c.config} + mutation := newCardMutation(c.config, OpCreate) + return &CardCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Card. func (c *CardClient) Update() *CardUpdate { - return &CardUpdate{config: c.config} + mutation := newCardMutation(c.config, OpUpdate) + return &CardUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -193,12 +209,15 @@ func (c *CardClient) UpdateOne(ca *Card) *CardUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CardClient) UpdateOneID(id string) *CardUpdateOne { - return &CardUpdateOne{config: c.config, id: id} + mutation := newCardMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CardUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Card. func (c *CardClient) Delete() *CardDelete { - return &CardDelete{config: c.config} + mutation := newCardMutation(c.config, OpDelete) + return &CardDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -208,7 +227,10 @@ func (c *CardClient) DeleteOne(ca *Card) *CardDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CardClient) DeleteOneID(id string) *CardDeleteOne { - return &CardDeleteOne{c.Delete().Where(card.ID(id))} + builder := c.Delete().Where(card.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CardDeleteOne{builder} } // Create returns a query builder for Card. @@ -248,6 +270,11 @@ func (c *CardClient) QuerySpec(ca *Card) *SpecQuery { return query } +// Hooks returns the client hooks. +func (c *CardClient) Hooks() []Hook { + return c.hooks.Card +} + // CommentClient is a client for the Comment schema. type CommentClient struct { config @@ -258,14 +285,22 @@ func NewCommentClient(c config) *CommentClient { return &CommentClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `comment.Hooks(f(g(h())))`. +func (c *CommentClient) Use(hooks ...Hook) { + c.hooks.Comment = append(c.hooks.Comment, hooks...) +} + // Create returns a create builder for Comment. func (c *CommentClient) Create() *CommentCreate { - return &CommentCreate{config: c.config} + mutation := newCommentMutation(c.config, OpCreate) + return &CommentCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Comment. func (c *CommentClient) Update() *CommentUpdate { - return &CommentUpdate{config: c.config} + mutation := newCommentMutation(c.config, OpUpdate) + return &CommentUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -275,12 +310,15 @@ func (c *CommentClient) UpdateOne(co *Comment) *CommentUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CommentClient) UpdateOneID(id string) *CommentUpdateOne { - return &CommentUpdateOne{config: c.config, id: id} + mutation := newCommentMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CommentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Comment. func (c *CommentClient) Delete() *CommentDelete { - return &CommentDelete{config: c.config} + mutation := newCommentMutation(c.config, OpDelete) + return &CommentDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -290,7 +328,10 @@ func (c *CommentClient) DeleteOne(co *Comment) *CommentDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CommentClient) DeleteOneID(id string) *CommentDeleteOne { - return &CommentDeleteOne{c.Delete().Where(comment.ID(id))} + builder := c.Delete().Where(comment.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CommentDeleteOne{builder} } // Create returns a query builder for Comment. @@ -312,6 +353,11 @@ func (c *CommentClient) GetX(ctx context.Context, id string) *Comment { return co } +// Hooks returns the client hooks. +func (c *CommentClient) Hooks() []Hook { + return c.hooks.Comment +} + // FieldTypeClient is a client for the FieldType schema. type FieldTypeClient struct { config @@ -322,14 +368,22 @@ func NewFieldTypeClient(c config) *FieldTypeClient { return &FieldTypeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `fieldtype.Hooks(f(g(h())))`. +func (c *FieldTypeClient) Use(hooks ...Hook) { + c.hooks.FieldType = append(c.hooks.FieldType, hooks...) +} + // Create returns a create builder for FieldType. func (c *FieldTypeClient) Create() *FieldTypeCreate { - return &FieldTypeCreate{config: c.config} + mutation := newFieldTypeMutation(c.config, OpCreate) + return &FieldTypeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for FieldType. func (c *FieldTypeClient) Update() *FieldTypeUpdate { - return &FieldTypeUpdate{config: c.config} + mutation := newFieldTypeMutation(c.config, OpUpdate) + return &FieldTypeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -339,12 +393,15 @@ func (c *FieldTypeClient) UpdateOne(ft *FieldType) *FieldTypeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *FieldTypeClient) UpdateOneID(id string) *FieldTypeUpdateOne { - return &FieldTypeUpdateOne{config: c.config, id: id} + mutation := newFieldTypeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &FieldTypeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for FieldType. func (c *FieldTypeClient) Delete() *FieldTypeDelete { - return &FieldTypeDelete{config: c.config} + mutation := newFieldTypeMutation(c.config, OpDelete) + return &FieldTypeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -354,7 +411,10 @@ func (c *FieldTypeClient) DeleteOne(ft *FieldType) *FieldTypeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *FieldTypeClient) DeleteOneID(id string) *FieldTypeDeleteOne { - return &FieldTypeDeleteOne{c.Delete().Where(fieldtype.ID(id))} + builder := c.Delete().Where(fieldtype.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &FieldTypeDeleteOne{builder} } // Create returns a query builder for FieldType. @@ -376,6 +436,11 @@ func (c *FieldTypeClient) GetX(ctx context.Context, id string) *FieldType { return ft } +// Hooks returns the client hooks. +func (c *FieldTypeClient) Hooks() []Hook { + return c.hooks.FieldType +} + // FileClient is a client for the File schema. type FileClient struct { config @@ -386,14 +451,22 @@ func NewFileClient(c config) *FileClient { return &FileClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `file.Hooks(f(g(h())))`. +func (c *FileClient) Use(hooks ...Hook) { + c.hooks.File = append(c.hooks.File, hooks...) +} + // Create returns a create builder for File. func (c *FileClient) Create() *FileCreate { - return &FileCreate{config: c.config} + mutation := newFileMutation(c.config, OpCreate) + return &FileCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for File. func (c *FileClient) Update() *FileUpdate { - return &FileUpdate{config: c.config} + mutation := newFileMutation(c.config, OpUpdate) + return &FileUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -403,12 +476,15 @@ func (c *FileClient) UpdateOne(f *File) *FileUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *FileClient) UpdateOneID(id string) *FileUpdateOne { - return &FileUpdateOne{config: c.config, id: id} + mutation := newFileMutation(c.config, OpUpdateOne) + mutation.id = &id + return &FileUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for File. func (c *FileClient) Delete() *FileDelete { - return &FileDelete{config: c.config} + mutation := newFileMutation(c.config, OpDelete) + return &FileDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -418,7 +494,10 @@ func (c *FileClient) DeleteOne(f *File) *FileDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *FileClient) DeleteOneID(id string) *FileDeleteOne { - return &FileDeleteOne{c.Delete().Where(file.ID(id))} + builder := c.Delete().Where(file.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &FileDeleteOne{builder} } // Create returns a query builder for File. @@ -458,6 +537,11 @@ func (c *FileClient) QueryType(f *File) *FileTypeQuery { return query } +// Hooks returns the client hooks. +func (c *FileClient) Hooks() []Hook { + return c.hooks.File +} + // FileTypeClient is a client for the FileType schema. type FileTypeClient struct { config @@ -468,14 +552,22 @@ func NewFileTypeClient(c config) *FileTypeClient { return &FileTypeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `filetype.Hooks(f(g(h())))`. +func (c *FileTypeClient) Use(hooks ...Hook) { + c.hooks.FileType = append(c.hooks.FileType, hooks...) +} + // Create returns a create builder for FileType. func (c *FileTypeClient) Create() *FileTypeCreate { - return &FileTypeCreate{config: c.config} + mutation := newFileTypeMutation(c.config, OpCreate) + return &FileTypeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for FileType. func (c *FileTypeClient) Update() *FileTypeUpdate { - return &FileTypeUpdate{config: c.config} + mutation := newFileTypeMutation(c.config, OpUpdate) + return &FileTypeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -485,12 +577,15 @@ func (c *FileTypeClient) UpdateOne(ft *FileType) *FileTypeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *FileTypeClient) UpdateOneID(id string) *FileTypeUpdateOne { - return &FileTypeUpdateOne{config: c.config, id: id} + mutation := newFileTypeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &FileTypeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for FileType. func (c *FileTypeClient) Delete() *FileTypeDelete { - return &FileTypeDelete{config: c.config} + mutation := newFileTypeMutation(c.config, OpDelete) + return &FileTypeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -500,7 +595,10 @@ func (c *FileTypeClient) DeleteOne(ft *FileType) *FileTypeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *FileTypeClient) DeleteOneID(id string) *FileTypeDeleteOne { - return &FileTypeDeleteOne{c.Delete().Where(filetype.ID(id))} + builder := c.Delete().Where(filetype.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &FileTypeDeleteOne{builder} } // Create returns a query builder for FileType. @@ -531,6 +629,11 @@ func (c *FileTypeClient) QueryFiles(ft *FileType) *FileQuery { return query } +// Hooks returns the client hooks. +func (c *FileTypeClient) Hooks() []Hook { + return c.hooks.FileType +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -541,14 +644,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -558,12 +669,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id string) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -573,7 +687,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id string) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -631,6 +748,11 @@ func (c *GroupClient) QueryInfo(gr *Group) *GroupInfoQuery { return query } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // GroupInfoClient is a client for the GroupInfo schema. type GroupInfoClient struct { config @@ -641,14 +763,22 @@ func NewGroupInfoClient(c config) *GroupInfoClient { return &GroupInfoClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `groupinfo.Hooks(f(g(h())))`. +func (c *GroupInfoClient) Use(hooks ...Hook) { + c.hooks.GroupInfo = append(c.hooks.GroupInfo, hooks...) +} + // Create returns a create builder for GroupInfo. func (c *GroupInfoClient) Create() *GroupInfoCreate { - return &GroupInfoCreate{config: c.config} + mutation := newGroupInfoMutation(c.config, OpCreate) + return &GroupInfoCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for GroupInfo. func (c *GroupInfoClient) Update() *GroupInfoUpdate { - return &GroupInfoUpdate{config: c.config} + mutation := newGroupInfoMutation(c.config, OpUpdate) + return &GroupInfoUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -658,12 +788,15 @@ func (c *GroupInfoClient) UpdateOne(gi *GroupInfo) *GroupInfoUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupInfoClient) UpdateOneID(id string) *GroupInfoUpdateOne { - return &GroupInfoUpdateOne{config: c.config, id: id} + mutation := newGroupInfoMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupInfoUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for GroupInfo. func (c *GroupInfoClient) Delete() *GroupInfoDelete { - return &GroupInfoDelete{config: c.config} + mutation := newGroupInfoMutation(c.config, OpDelete) + return &GroupInfoDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -673,7 +806,10 @@ func (c *GroupInfoClient) DeleteOne(gi *GroupInfo) *GroupInfoDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupInfoClient) DeleteOneID(id string) *GroupInfoDeleteOne { - return &GroupInfoDeleteOne{c.Delete().Where(groupinfo.ID(id))} + builder := c.Delete().Where(groupinfo.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupInfoDeleteOne{builder} } // Create returns a query builder for GroupInfo. @@ -704,6 +840,11 @@ func (c *GroupInfoClient) QueryGroups(gi *GroupInfo) *GroupQuery { return query } +// Hooks returns the client hooks. +func (c *GroupInfoClient) Hooks() []Hook { + return c.hooks.GroupInfo +} + // ItemClient is a client for the Item schema. type ItemClient struct { config @@ -714,14 +855,22 @@ func NewItemClient(c config) *ItemClient { return &ItemClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `item.Hooks(f(g(h())))`. +func (c *ItemClient) Use(hooks ...Hook) { + c.hooks.Item = append(c.hooks.Item, hooks...) +} + // Create returns a create builder for Item. func (c *ItemClient) Create() *ItemCreate { - return &ItemCreate{config: c.config} + mutation := newItemMutation(c.config, OpCreate) + return &ItemCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Item. func (c *ItemClient) Update() *ItemUpdate { - return &ItemUpdate{config: c.config} + mutation := newItemMutation(c.config, OpUpdate) + return &ItemUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -731,12 +880,15 @@ func (c *ItemClient) UpdateOne(i *Item) *ItemUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *ItemClient) UpdateOneID(id string) *ItemUpdateOne { - return &ItemUpdateOne{config: c.config, id: id} + mutation := newItemMutation(c.config, OpUpdateOne) + mutation.id = &id + return &ItemUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Item. func (c *ItemClient) Delete() *ItemDelete { - return &ItemDelete{config: c.config} + mutation := newItemMutation(c.config, OpDelete) + return &ItemDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -746,7 +898,10 @@ func (c *ItemClient) DeleteOne(i *Item) *ItemDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *ItemClient) DeleteOneID(id string) *ItemDeleteOne { - return &ItemDeleteOne{c.Delete().Where(item.ID(id))} + builder := c.Delete().Where(item.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &ItemDeleteOne{builder} } // Create returns a query builder for Item. @@ -768,6 +923,11 @@ func (c *ItemClient) GetX(ctx context.Context, id string) *Item { return i } +// Hooks returns the client hooks. +func (c *ItemClient) Hooks() []Hook { + return c.hooks.Item +} + // NodeClient is a client for the Node schema. type NodeClient struct { config @@ -778,14 +938,22 @@ func NewNodeClient(c config) *NodeClient { return &NodeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `node.Hooks(f(g(h())))`. +func (c *NodeClient) Use(hooks ...Hook) { + c.hooks.Node = append(c.hooks.Node, hooks...) +} + // Create returns a create builder for Node. func (c *NodeClient) Create() *NodeCreate { - return &NodeCreate{config: c.config} + mutation := newNodeMutation(c.config, OpCreate) + return &NodeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Node. func (c *NodeClient) Update() *NodeUpdate { - return &NodeUpdate{config: c.config} + mutation := newNodeMutation(c.config, OpUpdate) + return &NodeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -795,12 +963,15 @@ func (c *NodeClient) UpdateOne(n *Node) *NodeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *NodeClient) UpdateOneID(id string) *NodeUpdateOne { - return &NodeUpdateOne{config: c.config, id: id} + mutation := newNodeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &NodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Node. func (c *NodeClient) Delete() *NodeDelete { - return &NodeDelete{config: c.config} + mutation := newNodeMutation(c.config, OpDelete) + return &NodeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -810,7 +981,10 @@ func (c *NodeClient) DeleteOne(n *Node) *NodeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *NodeClient) DeleteOneID(id string) *NodeDeleteOne { - return &NodeDeleteOne{c.Delete().Where(node.ID(id))} + builder := c.Delete().Where(node.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &NodeDeleteOne{builder} } // Create returns a query builder for Node. @@ -850,6 +1024,11 @@ func (c *NodeClient) QueryNext(n *Node) *NodeQuery { return query } +// Hooks returns the client hooks. +func (c *NodeClient) Hooks() []Hook { + return c.hooks.Node +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -860,14 +1039,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -877,12 +1064,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id string) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -892,7 +1082,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id string) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -932,6 +1125,11 @@ func (c *PetClient) QueryOwner(pe *Pet) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // SpecClient is a client for the Spec schema. type SpecClient struct { config @@ -942,14 +1140,22 @@ func NewSpecClient(c config) *SpecClient { return &SpecClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `spec.Hooks(f(g(h())))`. +func (c *SpecClient) Use(hooks ...Hook) { + c.hooks.Spec = append(c.hooks.Spec, hooks...) +} + // Create returns a create builder for Spec. func (c *SpecClient) Create() *SpecCreate { - return &SpecCreate{config: c.config} + mutation := newSpecMutation(c.config, OpCreate) + return &SpecCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Spec. func (c *SpecClient) Update() *SpecUpdate { - return &SpecUpdate{config: c.config} + mutation := newSpecMutation(c.config, OpUpdate) + return &SpecUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -959,12 +1165,15 @@ func (c *SpecClient) UpdateOne(s *Spec) *SpecUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *SpecClient) UpdateOneID(id string) *SpecUpdateOne { - return &SpecUpdateOne{config: c.config, id: id} + mutation := newSpecMutation(c.config, OpUpdateOne) + mutation.id = &id + return &SpecUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Spec. func (c *SpecClient) Delete() *SpecDelete { - return &SpecDelete{config: c.config} + mutation := newSpecMutation(c.config, OpDelete) + return &SpecDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -974,7 +1183,10 @@ func (c *SpecClient) DeleteOne(s *Spec) *SpecDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *SpecClient) DeleteOneID(id string) *SpecDeleteOne { - return &SpecDeleteOne{c.Delete().Where(spec.ID(id))} + builder := c.Delete().Where(spec.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &SpecDeleteOne{builder} } // Create returns a query builder for Spec. @@ -1005,6 +1217,11 @@ func (c *SpecClient) QueryCard(s *Spec) *CardQuery { return query } +// Hooks returns the client hooks. +func (c *SpecClient) Hooks() []Hook { + return c.hooks.Spec +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -1015,14 +1232,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -1032,12 +1257,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id string) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -1047,7 +1275,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id string) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -1167,3 +1398,8 @@ func (c *UserClient) QueryParent(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/gremlin/ent/comment/comment.go b/entc/integration/gremlin/ent/comment/comment.go index 771cd9e0c..0309e0ce3 100644 --- a/entc/integration/gremlin/ent/comment/comment.go +++ b/entc/integration/gremlin/ent/comment/comment.go @@ -10,11 +10,8 @@ const ( // Label holds the string label denoting the comment type in the database. Label = "comment" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldUniqueInt holds the string denoting the unique_int vertex property in the database. - FieldUniqueInt = "unique_int" - // FieldUniqueFloat holds the string denoting the unique_float vertex property in the database. - FieldUniqueFloat = "unique_float" - // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. + FieldID = "id" // FieldUniqueInt holds the string denoting the unique_int vertex property in the database. + FieldUniqueInt = "unique_int" // FieldUniqueFloat holds the string denoting the unique_float vertex property in the database. + FieldUniqueFloat = "unique_float" // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. FieldNillableInt = "nillable_int" ) diff --git a/entc/integration/gremlin/ent/comment_create.go b/entc/integration/gremlin/ent/comment_create.go index 94af519e4..05937b338 100644 --- a/entc/integration/gremlin/ent/comment_create.go +++ b/entc/integration/gremlin/ent/comment_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -21,26 +22,25 @@ import ( // CommentCreate is the builder for creating a Comment entity. type CommentCreate struct { config - unique_int *int - unique_float *float64 - nillable_int *int + mutation *CommentMutation + hooks []Hook } // SetUniqueInt sets the unique_int field. func (cc *CommentCreate) SetUniqueInt(i int) *CommentCreate { - cc.unique_int = &i + cc.mutation.SetUniqueInt(i) return cc } // SetUniqueFloat sets the unique_float field. func (cc *CommentCreate) SetUniqueFloat(f float64) *CommentCreate { - cc.unique_float = &f + cc.mutation.SetUniqueFloat(f) return cc } // SetNillableInt sets the nillable_int field. func (cc *CommentCreate) SetNillableInt(i int) *CommentCreate { - cc.nillable_int = &i + cc.mutation.SetNillableInt(i) return cc } @@ -54,13 +54,36 @@ func (cc *CommentCreate) SetNillableNillableInt(i *int) *CommentCreate { // Save creates the Comment in the database. func (cc *CommentCreate) Save(ctx context.Context) (*Comment, error) { - if cc.unique_int == nil { + if _, ok := cc.mutation.UniqueInt(); !ok { return nil, errors.New("ent: missing required field \"unique_int\"") } - if cc.unique_float == nil { + if _, ok := cc.mutation.UniqueFloat(); !ok { return nil, errors.New("ent: missing required field \"unique_float\"") } - return cc.gremlinSave(ctx) + var ( + err error + node *Comment + ) + if len(cc.hooks) == 0 { + node, err = cc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.gremlinSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -95,22 +118,22 @@ func (cc *CommentCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 2) v := g.AddV(comment.Label) - if cc.unique_int != nil { + if value, ok := cc.mutation.UniqueInt(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(comment.Label, comment.FieldUniqueInt, *cc.unique_int).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, *cc.unique_int)), + pred: g.V().Has(comment.Label, comment.FieldUniqueInt, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, value)), }) - v.Property(dsl.Single, comment.FieldUniqueInt, *cc.unique_int) + v.Property(dsl.Single, comment.FieldUniqueInt, value) } - if cc.unique_float != nil { + if value, ok := cc.mutation.UniqueFloat(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, *cc.unique_float).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, *cc.unique_float)), + pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, value)), }) - v.Property(dsl.Single, comment.FieldUniqueFloat, *cc.unique_float) + v.Property(dsl.Single, comment.FieldUniqueFloat, value) } - if cc.nillable_int != nil { - v.Property(dsl.Single, comment.FieldNillableInt, *cc.nillable_int) + if value, ok := cc.mutation.NillableInt(); ok { + v.Property(dsl.Single, comment.FieldNillableInt, value) } if len(constraints) == 0 { return v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/comment_delete.go b/entc/integration/gremlin/ent/comment_delete.go index a6621cf03..897769534 100644 --- a/entc/integration/gremlin/ent/comment_delete.go +++ b/entc/integration/gremlin/ent/comment_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // CommentDelete is the builder for deleting a Comment entity. type CommentDelete struct { config + hooks []Hook + mutation *CommentMutation predicates []predicate.Comment } @@ -31,7 +34,30 @@ func (cd *CommentDelete) Where(ps ...predicate.Comment) *CommentDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CommentDelete) Exec(ctx context.Context) (int, error) { - return cd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.gremlinExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/comment_update.go b/entc/integration/gremlin/ent/comment_update.go index 5c2979ae2..112967378 100644 --- a/entc/integration/gremlin/ent/comment_update.go +++ b/entc/integration/gremlin/ent/comment_update.go @@ -22,14 +22,9 @@ import ( // CommentUpdate is the builder for updating Comment entities. type CommentUpdate struct { config - unique_int *int - addunique_int *int - unique_float *float64 - addunique_float *float64 - nillable_int *int - addnillable_int *int - clearnillable_int bool - predicates []predicate.Comment + hooks []Hook + mutation *CommentMutation + predicates []predicate.Comment } // Where adds a new predicate for the builder. @@ -40,42 +35,34 @@ func (cu *CommentUpdate) Where(ps ...predicate.Comment) *CommentUpdate { // SetUniqueInt sets the unique_int field. func (cu *CommentUpdate) SetUniqueInt(i int) *CommentUpdate { - cu.unique_int = &i - cu.addunique_int = nil + cu.mutation.ResetUniqueInt() + cu.mutation.SetUniqueInt(i) return cu } // AddUniqueInt adds i to unique_int. func (cu *CommentUpdate) AddUniqueInt(i int) *CommentUpdate { - if cu.addunique_int == nil { - cu.addunique_int = &i - } else { - *cu.addunique_int += i - } + cu.mutation.AddUniqueInt(i) return cu } // SetUniqueFloat sets the unique_float field. func (cu *CommentUpdate) SetUniqueFloat(f float64) *CommentUpdate { - cu.unique_float = &f - cu.addunique_float = nil + cu.mutation.ResetUniqueFloat() + cu.mutation.SetUniqueFloat(f) return cu } // AddUniqueFloat adds f to unique_float. func (cu *CommentUpdate) AddUniqueFloat(f float64) *CommentUpdate { - if cu.addunique_float == nil { - cu.addunique_float = &f - } else { - *cu.addunique_float += f - } + cu.mutation.AddUniqueFloat(f) return cu } // SetNillableInt sets the nillable_int field. func (cu *CommentUpdate) SetNillableInt(i int) *CommentUpdate { - cu.nillable_int = &i - cu.addnillable_int = nil + cu.mutation.ResetNillableInt() + cu.mutation.SetNillableInt(i) return cu } @@ -89,24 +76,42 @@ func (cu *CommentUpdate) SetNillableNillableInt(i *int) *CommentUpdate { // AddNillableInt adds i to nillable_int. func (cu *CommentUpdate) AddNillableInt(i int) *CommentUpdate { - if cu.addnillable_int == nil { - cu.addnillable_int = &i - } else { - *cu.addnillable_int += i - } + cu.mutation.AddNillableInt(i) return cu } // ClearNillableInt clears the value of nillable_int. func (cu *CommentUpdate) ClearNillableInt() *CommentUpdate { - cu.nillable_int = nil - cu.clearnillable_int = true + cu.mutation.ClearNillableInt() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CommentUpdate) Save(ctx context.Context) (int, error) { - return cu.gremlinSave(ctx) + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.gremlinSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -159,44 +164,44 @@ func (cu *CommentUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := cu.unique_int; value != nil { + if value, ok := cu.mutation.UniqueInt(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(comment.Label, comment.FieldUniqueInt, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, *value)), + pred: g.V().Has(comment.Label, comment.FieldUniqueInt, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, value)), }) - v.Property(dsl.Single, comment.FieldUniqueInt, *value) + v.Property(dsl.Single, comment.FieldUniqueInt, value) } - if value := cu.addunique_int; value != nil { - addValue := rv.Clone().Union(__.Values(comment.FieldUniqueInt), __.Constant(*value)).Sum().Next() + if value, ok := cu.mutation.AddedUniqueInt(); ok { + addValue := rv.Clone().Union(__.Values(comment.FieldUniqueInt), __.Constant(value)).Sum().Next() constraints = append(constraints, &constraint{ pred: g.V().Has(comment.Label, comment.FieldUniqueInt, addValue).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, fmt.Sprintf("+= %v", *value))), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, fmt.Sprintf("+= %v", value))), }) - v.Property(dsl.Single, comment.FieldUniqueInt, __.Union(__.Values(comment.FieldUniqueInt), __.Constant(*value)).Sum()) + v.Property(dsl.Single, comment.FieldUniqueInt, __.Union(__.Values(comment.FieldUniqueInt), __.Constant(value)).Sum()) } - if value := cu.unique_float; value != nil { + if value, ok := cu.mutation.UniqueFloat(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, *value)), + pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, value)), }) - v.Property(dsl.Single, comment.FieldUniqueFloat, *value) + v.Property(dsl.Single, comment.FieldUniqueFloat, value) } - if value := cu.addunique_float; value != nil { - addValue := rv.Clone().Union(__.Values(comment.FieldUniqueFloat), __.Constant(*value)).Sum().Next() + if value, ok := cu.mutation.AddedUniqueFloat(); ok { + addValue := rv.Clone().Union(__.Values(comment.FieldUniqueFloat), __.Constant(value)).Sum().Next() constraints = append(constraints, &constraint{ pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, addValue).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, fmt.Sprintf("+= %v", *value))), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, fmt.Sprintf("+= %v", value))), }) - v.Property(dsl.Single, comment.FieldUniqueFloat, __.Union(__.Values(comment.FieldUniqueFloat), __.Constant(*value)).Sum()) + v.Property(dsl.Single, comment.FieldUniqueFloat, __.Union(__.Values(comment.FieldUniqueFloat), __.Constant(value)).Sum()) } - if value := cu.nillable_int; value != nil { - v.Property(dsl.Single, comment.FieldNillableInt, *value) + if value, ok := cu.mutation.NillableInt(); ok { + v.Property(dsl.Single, comment.FieldNillableInt, value) } - if value := cu.addnillable_int; value != nil { - v.Property(dsl.Single, comment.FieldNillableInt, __.Union(__.Values(comment.FieldNillableInt), __.Constant(*value)).Sum()) + if value, ok := cu.mutation.AddedNillableInt(); ok { + v.Property(dsl.Single, comment.FieldNillableInt, __.Union(__.Values(comment.FieldNillableInt), __.Constant(value)).Sum()) } var properties []interface{} - if cu.clearnillable_int { + if cu.mutation.NillableIntCleared() { properties = append(properties, comment.FieldNillableInt) } if len(properties) > 0 { @@ -220,54 +225,40 @@ func (cu *CommentUpdate) gremlin() *dsl.Traversal { // CommentUpdateOne is the builder for updating a single Comment entity. type CommentUpdateOne struct { config - id string - unique_int *int - addunique_int *int - unique_float *float64 - addunique_float *float64 - nillable_int *int - addnillable_int *int - clearnillable_int bool + hooks []Hook + mutation *CommentMutation } // SetUniqueInt sets the unique_int field. func (cuo *CommentUpdateOne) SetUniqueInt(i int) *CommentUpdateOne { - cuo.unique_int = &i - cuo.addunique_int = nil + cuo.mutation.ResetUniqueInt() + cuo.mutation.SetUniqueInt(i) return cuo } // AddUniqueInt adds i to unique_int. func (cuo *CommentUpdateOne) AddUniqueInt(i int) *CommentUpdateOne { - if cuo.addunique_int == nil { - cuo.addunique_int = &i - } else { - *cuo.addunique_int += i - } + cuo.mutation.AddUniqueInt(i) return cuo } // SetUniqueFloat sets the unique_float field. func (cuo *CommentUpdateOne) SetUniqueFloat(f float64) *CommentUpdateOne { - cuo.unique_float = &f - cuo.addunique_float = nil + cuo.mutation.ResetUniqueFloat() + cuo.mutation.SetUniqueFloat(f) return cuo } // AddUniqueFloat adds f to unique_float. func (cuo *CommentUpdateOne) AddUniqueFloat(f float64) *CommentUpdateOne { - if cuo.addunique_float == nil { - cuo.addunique_float = &f - } else { - *cuo.addunique_float += f - } + cuo.mutation.AddUniqueFloat(f) return cuo } // SetNillableInt sets the nillable_int field. func (cuo *CommentUpdateOne) SetNillableInt(i int) *CommentUpdateOne { - cuo.nillable_int = &i - cuo.addnillable_int = nil + cuo.mutation.ResetNillableInt() + cuo.mutation.SetNillableInt(i) return cuo } @@ -281,24 +272,42 @@ func (cuo *CommentUpdateOne) SetNillableNillableInt(i *int) *CommentUpdateOne { // AddNillableInt adds i to nillable_int. func (cuo *CommentUpdateOne) AddNillableInt(i int) *CommentUpdateOne { - if cuo.addnillable_int == nil { - cuo.addnillable_int = &i - } else { - *cuo.addnillable_int += i - } + cuo.mutation.AddNillableInt(i) return cuo } // ClearNillableInt clears the value of nillable_int. func (cuo *CommentUpdateOne) ClearNillableInt() *CommentUpdateOne { - cuo.nillable_int = nil - cuo.clearnillable_int = true + cuo.mutation.ClearNillableInt() return cuo } // Save executes the query and returns the updated entity. func (cuo *CommentUpdateOne) Save(ctx context.Context) (*Comment, error) { - return cuo.gremlinSave(ctx) + var ( + err error + node *Comment + ) + if len(cuo.hooks) == 0 { + node, err = cuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.gremlinSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -325,7 +334,11 @@ func (cuo *CommentUpdateOne) ExecX(ctx context.Context) { func (cuo *CommentUpdateOne) gremlinSave(ctx context.Context) (*Comment, error) { res := &gremlin.Response{} - query, bindings := cuo.gremlin(cuo.id).Query() + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Comment.ID for update") + } + query, bindings := cuo.gremlin(id).Query() if err := cuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -352,44 +365,44 @@ func (cuo *CommentUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := cuo.unique_int; value != nil { + if value, ok := cuo.mutation.UniqueInt(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(comment.Label, comment.FieldUniqueInt, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, *value)), + pred: g.V().Has(comment.Label, comment.FieldUniqueInt, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, value)), }) - v.Property(dsl.Single, comment.FieldUniqueInt, *value) + v.Property(dsl.Single, comment.FieldUniqueInt, value) } - if value := cuo.addunique_int; value != nil { - addValue := rv.Clone().Union(__.Values(comment.FieldUniqueInt), __.Constant(*value)).Sum().Next() + if value, ok := cuo.mutation.AddedUniqueInt(); ok { + addValue := rv.Clone().Union(__.Values(comment.FieldUniqueInt), __.Constant(value)).Sum().Next() constraints = append(constraints, &constraint{ pred: g.V().Has(comment.Label, comment.FieldUniqueInt, addValue).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, fmt.Sprintf("+= %v", *value))), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueInt, fmt.Sprintf("+= %v", value))), }) - v.Property(dsl.Single, comment.FieldUniqueInt, __.Union(__.Values(comment.FieldUniqueInt), __.Constant(*value)).Sum()) + v.Property(dsl.Single, comment.FieldUniqueInt, __.Union(__.Values(comment.FieldUniqueInt), __.Constant(value)).Sum()) } - if value := cuo.unique_float; value != nil { + if value, ok := cuo.mutation.UniqueFloat(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, *value)), + pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, value)), }) - v.Property(dsl.Single, comment.FieldUniqueFloat, *value) + v.Property(dsl.Single, comment.FieldUniqueFloat, value) } - if value := cuo.addunique_float; value != nil { - addValue := rv.Clone().Union(__.Values(comment.FieldUniqueFloat), __.Constant(*value)).Sum().Next() + if value, ok := cuo.mutation.AddedUniqueFloat(); ok { + addValue := rv.Clone().Union(__.Values(comment.FieldUniqueFloat), __.Constant(value)).Sum().Next() constraints = append(constraints, &constraint{ pred: g.V().Has(comment.Label, comment.FieldUniqueFloat, addValue).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, fmt.Sprintf("+= %v", *value))), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(comment.Label, comment.FieldUniqueFloat, fmt.Sprintf("+= %v", value))), }) - v.Property(dsl.Single, comment.FieldUniqueFloat, __.Union(__.Values(comment.FieldUniqueFloat), __.Constant(*value)).Sum()) + v.Property(dsl.Single, comment.FieldUniqueFloat, __.Union(__.Values(comment.FieldUniqueFloat), __.Constant(value)).Sum()) } - if value := cuo.nillable_int; value != nil { - v.Property(dsl.Single, comment.FieldNillableInt, *value) + if value, ok := cuo.mutation.NillableInt(); ok { + v.Property(dsl.Single, comment.FieldNillableInt, value) } - if value := cuo.addnillable_int; value != nil { - v.Property(dsl.Single, comment.FieldNillableInt, __.Union(__.Values(comment.FieldNillableInt), __.Constant(*value)).Sum()) + if value, ok := cuo.mutation.AddedNillableInt(); ok { + v.Property(dsl.Single, comment.FieldNillableInt, __.Union(__.Values(comment.FieldNillableInt), __.Constant(value)).Sum()) } var properties []interface{} - if cuo.clearnillable_int { + if cuo.mutation.NillableIntCleared() { properties = append(properties, comment.FieldNillableInt) } if len(properties) > 0 { diff --git a/entc/integration/gremlin/ent/config.go b/entc/integration/gremlin/ent/config.go index dd64c4cf6..d034d7be0 100644 --- a/entc/integration/gremlin/ent/config.go +++ b/entc/integration/gremlin/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,24 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Card []ent.Hook + Comment []ent.Hook + FieldType []ent.Hook + File []ent.Hook + FileType []ent.Hook + Group []ent.Hook + GroupInfo []ent.Hook + Item []ent.Hook + Node []ent.Hook + Pet []ent.Hook + Spec []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/gremlin/ent/ent.go b/entc/integration/gremlin/ent/ent.go index 86de0c68a..f6be08637 100644 --- a/entc/integration/gremlin/ent/ent.go +++ b/entc/integration/gremlin/ent/ent.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/encoding/graphson" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -18,6 +19,16 @@ import ( "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*dsl.Traversal) diff --git a/entc/integration/gremlin/ent/fieldtype/fieldtype.go b/entc/integration/gremlin/ent/fieldtype/fieldtype.go index 040e60590..159f7970a 100644 --- a/entc/integration/gremlin/ent/fieldtype/fieldtype.go +++ b/entc/integration/gremlin/ent/fieldtype/fieldtype.go @@ -8,72 +8,42 @@ package fieldtype import ( "fmt" - - "github.com/facebookincubator/ent/entc/integration/ent/schema" ) const ( // Label holds the string label denoting the fieldtype type in the database. Label = "field_type" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldInt holds the string denoting the int vertex property in the database. - FieldInt = "int" - // FieldInt8 holds the string denoting the int8 vertex property in the database. - FieldInt8 = "int8" - // FieldInt16 holds the string denoting the int16 vertex property in the database. - FieldInt16 = "int16" - // FieldInt32 holds the string denoting the int32 vertex property in the database. - FieldInt32 = "int32" - // FieldInt64 holds the string denoting the int64 vertex property in the database. - FieldInt64 = "int64" - // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. - FieldOptionalInt = "optional_int" - // FieldOptionalInt8 holds the string denoting the optional_int8 vertex property in the database. - FieldOptionalInt8 = "optional_int8" - // FieldOptionalInt16 holds the string denoting the optional_int16 vertex property in the database. - FieldOptionalInt16 = "optional_int16" - // FieldOptionalInt32 holds the string denoting the optional_int32 vertex property in the database. - FieldOptionalInt32 = "optional_int32" - // FieldOptionalInt64 holds the string denoting the optional_int64 vertex property in the database. - FieldOptionalInt64 = "optional_int64" - // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. - FieldNillableInt = "nillable_int" - // FieldNillableInt8 holds the string denoting the nillable_int8 vertex property in the database. - FieldNillableInt8 = "nillable_int8" - // FieldNillableInt16 holds the string denoting the nillable_int16 vertex property in the database. - FieldNillableInt16 = "nillable_int16" - // FieldNillableInt32 holds the string denoting the nillable_int32 vertex property in the database. - FieldNillableInt32 = "nillable_int32" - // FieldNillableInt64 holds the string denoting the nillable_int64 vertex property in the database. - FieldNillableInt64 = "nillable_int64" - // FieldValidateOptionalInt32 holds the string denoting the validate_optional_int32 vertex property in the database. - FieldValidateOptionalInt32 = "validate_optional_int32" - // FieldOptionalUint holds the string denoting the optional_uint vertex property in the database. - FieldOptionalUint = "optional_uint" - // FieldOptionalUint8 holds the string denoting the optional_uint8 vertex property in the database. - FieldOptionalUint8 = "optional_uint8" - // FieldOptionalUint16 holds the string denoting the optional_uint16 vertex property in the database. - FieldOptionalUint16 = "optional_uint16" - // FieldOptionalUint32 holds the string denoting the optional_uint32 vertex property in the database. - FieldOptionalUint32 = "optional_uint32" - // FieldOptionalUint64 holds the string denoting the optional_uint64 vertex property in the database. - FieldOptionalUint64 = "optional_uint64" - // FieldState holds the string denoting the state vertex property in the database. - FieldState = "state" - // FieldOptionalFloat holds the string denoting the optional_float vertex property in the database. - FieldOptionalFloat = "optional_float" - // FieldOptionalFloat32 holds the string denoting the optional_float32 vertex property in the database. - FieldOptionalFloat32 = "optional_float32" + FieldID = "id" // FieldInt holds the string denoting the int vertex property in the database. + FieldInt = "int" // FieldInt8 holds the string denoting the int8 vertex property in the database. + FieldInt8 = "int8" // FieldInt16 holds the string denoting the int16 vertex property in the database. + FieldInt16 = "int16" // FieldInt32 holds the string denoting the int32 vertex property in the database. + FieldInt32 = "int32" // FieldInt64 holds the string denoting the int64 vertex property in the database. + FieldInt64 = "int64" // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. + FieldOptionalInt = "optional_int" // FieldOptionalInt8 holds the string denoting the optional_int8 vertex property in the database. + FieldOptionalInt8 = "optional_int8" // FieldOptionalInt16 holds the string denoting the optional_int16 vertex property in the database. + FieldOptionalInt16 = "optional_int16" // FieldOptionalInt32 holds the string denoting the optional_int32 vertex property in the database. + FieldOptionalInt32 = "optional_int32" // FieldOptionalInt64 holds the string denoting the optional_int64 vertex property in the database. + FieldOptionalInt64 = "optional_int64" // FieldNillableInt holds the string denoting the nillable_int vertex property in the database. + FieldNillableInt = "nillable_int" // FieldNillableInt8 holds the string denoting the nillable_int8 vertex property in the database. + FieldNillableInt8 = "nillable_int8" // FieldNillableInt16 holds the string denoting the nillable_int16 vertex property in the database. + FieldNillableInt16 = "nillable_int16" // FieldNillableInt32 holds the string denoting the nillable_int32 vertex property in the database. + FieldNillableInt32 = "nillable_int32" // FieldNillableInt64 holds the string denoting the nillable_int64 vertex property in the database. + FieldNillableInt64 = "nillable_int64" // FieldValidateOptionalInt32 holds the string denoting the validate_optional_int32 vertex property in the database. + FieldValidateOptionalInt32 = "validate_optional_int32" // FieldOptionalUint holds the string denoting the optional_uint vertex property in the database. + FieldOptionalUint = "optional_uint" // FieldOptionalUint8 holds the string denoting the optional_uint8 vertex property in the database. + FieldOptionalUint8 = "optional_uint8" // FieldOptionalUint16 holds the string denoting the optional_uint16 vertex property in the database. + FieldOptionalUint16 = "optional_uint16" // FieldOptionalUint32 holds the string denoting the optional_uint32 vertex property in the database. + FieldOptionalUint32 = "optional_uint32" // FieldOptionalUint64 holds the string denoting the optional_uint64 vertex property in the database. + FieldOptionalUint64 = "optional_uint64" // FieldState holds the string denoting the state vertex property in the database. + FieldState = "state" // FieldOptionalFloat holds the string denoting the optional_float vertex property in the database. + FieldOptionalFloat = "optional_float" // FieldOptionalFloat32 holds the string denoting the optional_float32 vertex property in the database. + FieldOptionalFloat32 = "optional_float32" ) var ( - fields = schema.FieldType{}.Fields() - - // descValidateOptionalInt32 is the schema descriptor for validate_optional_int32 field. - descValidateOptionalInt32 = fields[15].Descriptor() // ValidateOptionalInt32Validator is a validator for the "validate_optional_int32" field. It is called by the builders before save. - ValidateOptionalInt32Validator = descValidateOptionalInt32.Validators[0].(func(int32) error) + ValidateOptionalInt32Validator func(int32) error ) // State defines the type for the state enum field. diff --git a/entc/integration/gremlin/ent/fieldtype_create.go b/entc/integration/gremlin/ent/fieldtype_create.go index 9a319a66f..926d63321 100644 --- a/entc/integration/gremlin/ent/fieldtype_create.go +++ b/entc/integration/gremlin/ent/fieldtype_create.go @@ -20,65 +20,43 @@ import ( // FieldTypeCreate is the builder for creating a FieldType entity. type FieldTypeCreate struct { config - int *int - int8 *int8 - int16 *int16 - int32 *int32 - int64 *int64 - optional_int *int - optional_int8 *int8 - optional_int16 *int16 - optional_int32 *int32 - optional_int64 *int64 - nillable_int *int - nillable_int8 *int8 - nillable_int16 *int16 - nillable_int32 *int32 - nillable_int64 *int64 - validate_optional_int32 *int32 - optional_uint *uint - optional_uint8 *uint8 - optional_uint16 *uint16 - optional_uint32 *uint32 - optional_uint64 *uint64 - state *fieldtype.State - optional_float *float64 - optional_float32 *float32 + mutation *FieldTypeMutation + hooks []Hook } // SetInt sets the int field. func (ftc *FieldTypeCreate) SetInt(i int) *FieldTypeCreate { - ftc.int = &i + ftc.mutation.SetInt(i) return ftc } // SetInt8 sets the int8 field. func (ftc *FieldTypeCreate) SetInt8(i int8) *FieldTypeCreate { - ftc.int8 = &i + ftc.mutation.SetInt8(i) return ftc } // SetInt16 sets the int16 field. func (ftc *FieldTypeCreate) SetInt16(i int16) *FieldTypeCreate { - ftc.int16 = &i + ftc.mutation.SetInt16(i) return ftc } // SetInt32 sets the int32 field. func (ftc *FieldTypeCreate) SetInt32(i int32) *FieldTypeCreate { - ftc.int32 = &i + ftc.mutation.SetInt32(i) return ftc } // SetInt64 sets the int64 field. func (ftc *FieldTypeCreate) SetInt64(i int64) *FieldTypeCreate { - ftc.int64 = &i + ftc.mutation.SetInt64(i) return ftc } // SetOptionalInt sets the optional_int field. func (ftc *FieldTypeCreate) SetOptionalInt(i int) *FieldTypeCreate { - ftc.optional_int = &i + ftc.mutation.SetOptionalInt(i) return ftc } @@ -92,7 +70,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt(i *int) *FieldTypeCreate { // SetOptionalInt8 sets the optional_int8 field. func (ftc *FieldTypeCreate) SetOptionalInt8(i int8) *FieldTypeCreate { - ftc.optional_int8 = &i + ftc.mutation.SetOptionalInt8(i) return ftc } @@ -106,7 +84,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt8(i *int8) *FieldTypeCreate { // SetOptionalInt16 sets the optional_int16 field. func (ftc *FieldTypeCreate) SetOptionalInt16(i int16) *FieldTypeCreate { - ftc.optional_int16 = &i + ftc.mutation.SetOptionalInt16(i) return ftc } @@ -120,7 +98,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt16(i *int16) *FieldTypeCreate // SetOptionalInt32 sets the optional_int32 field. func (ftc *FieldTypeCreate) SetOptionalInt32(i int32) *FieldTypeCreate { - ftc.optional_int32 = &i + ftc.mutation.SetOptionalInt32(i) return ftc } @@ -134,7 +112,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt32(i *int32) *FieldTypeCreate // SetOptionalInt64 sets the optional_int64 field. func (ftc *FieldTypeCreate) SetOptionalInt64(i int64) *FieldTypeCreate { - ftc.optional_int64 = &i + ftc.mutation.SetOptionalInt64(i) return ftc } @@ -148,7 +126,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalInt64(i *int64) *FieldTypeCreate // SetNillableInt sets the nillable_int field. func (ftc *FieldTypeCreate) SetNillableInt(i int) *FieldTypeCreate { - ftc.nillable_int = &i + ftc.mutation.SetNillableInt(i) return ftc } @@ -162,7 +140,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt(i *int) *FieldTypeCreate { // SetNillableInt8 sets the nillable_int8 field. func (ftc *FieldTypeCreate) SetNillableInt8(i int8) *FieldTypeCreate { - ftc.nillable_int8 = &i + ftc.mutation.SetNillableInt8(i) return ftc } @@ -176,7 +154,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt8(i *int8) *FieldTypeCreate { // SetNillableInt16 sets the nillable_int16 field. func (ftc *FieldTypeCreate) SetNillableInt16(i int16) *FieldTypeCreate { - ftc.nillable_int16 = &i + ftc.mutation.SetNillableInt16(i) return ftc } @@ -190,7 +168,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt16(i *int16) *FieldTypeCreate // SetNillableInt32 sets the nillable_int32 field. func (ftc *FieldTypeCreate) SetNillableInt32(i int32) *FieldTypeCreate { - ftc.nillable_int32 = &i + ftc.mutation.SetNillableInt32(i) return ftc } @@ -204,7 +182,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt32(i *int32) *FieldTypeCreate // SetNillableInt64 sets the nillable_int64 field. func (ftc *FieldTypeCreate) SetNillableInt64(i int64) *FieldTypeCreate { - ftc.nillable_int64 = &i + ftc.mutation.SetNillableInt64(i) return ftc } @@ -218,7 +196,7 @@ func (ftc *FieldTypeCreate) SetNillableNillableInt64(i *int64) *FieldTypeCreate // SetValidateOptionalInt32 sets the validate_optional_int32 field. func (ftc *FieldTypeCreate) SetValidateOptionalInt32(i int32) *FieldTypeCreate { - ftc.validate_optional_int32 = &i + ftc.mutation.SetValidateOptionalInt32(i) return ftc } @@ -232,7 +210,7 @@ func (ftc *FieldTypeCreate) SetNillableValidateOptionalInt32(i *int32) *FieldTyp // SetOptionalUint sets the optional_uint field. func (ftc *FieldTypeCreate) SetOptionalUint(u uint) *FieldTypeCreate { - ftc.optional_uint = &u + ftc.mutation.SetOptionalUint(u) return ftc } @@ -246,7 +224,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint(u *uint) *FieldTypeCreate { // SetOptionalUint8 sets the optional_uint8 field. func (ftc *FieldTypeCreate) SetOptionalUint8(u uint8) *FieldTypeCreate { - ftc.optional_uint8 = &u + ftc.mutation.SetOptionalUint8(u) return ftc } @@ -260,7 +238,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint8(u *uint8) *FieldTypeCreate // SetOptionalUint16 sets the optional_uint16 field. func (ftc *FieldTypeCreate) SetOptionalUint16(u uint16) *FieldTypeCreate { - ftc.optional_uint16 = &u + ftc.mutation.SetOptionalUint16(u) return ftc } @@ -274,7 +252,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint16(u *uint16) *FieldTypeCreat // SetOptionalUint32 sets the optional_uint32 field. func (ftc *FieldTypeCreate) SetOptionalUint32(u uint32) *FieldTypeCreate { - ftc.optional_uint32 = &u + ftc.mutation.SetOptionalUint32(u) return ftc } @@ -288,7 +266,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint32(u *uint32) *FieldTypeCreat // SetOptionalUint64 sets the optional_uint64 field. func (ftc *FieldTypeCreate) SetOptionalUint64(u uint64) *FieldTypeCreate { - ftc.optional_uint64 = &u + ftc.mutation.SetOptionalUint64(u) return ftc } @@ -302,7 +280,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalUint64(u *uint64) *FieldTypeCreat // SetState sets the state field. func (ftc *FieldTypeCreate) SetState(f fieldtype.State) *FieldTypeCreate { - ftc.state = &f + ftc.mutation.SetState(f) return ftc } @@ -316,7 +294,7 @@ func (ftc *FieldTypeCreate) SetNillableState(f *fieldtype.State) *FieldTypeCreat // SetOptionalFloat sets the optional_float field. func (ftc *FieldTypeCreate) SetOptionalFloat(f float64) *FieldTypeCreate { - ftc.optional_float = &f + ftc.mutation.SetOptionalFloat(f) return ftc } @@ -330,7 +308,7 @@ func (ftc *FieldTypeCreate) SetNillableOptionalFloat(f *float64) *FieldTypeCreat // SetOptionalFloat32 sets the optional_float32 field. func (ftc *FieldTypeCreate) SetOptionalFloat32(f float32) *FieldTypeCreate { - ftc.optional_float32 = &f + ftc.mutation.SetOptionalFloat32(f) return ftc } @@ -344,32 +322,55 @@ func (ftc *FieldTypeCreate) SetNillableOptionalFloat32(f *float32) *FieldTypeCre // Save creates the FieldType in the database. func (ftc *FieldTypeCreate) Save(ctx context.Context) (*FieldType, error) { - if ftc.int == nil { + if _, ok := ftc.mutation.Int(); !ok { return nil, errors.New("ent: missing required field \"int\"") } - if ftc.int8 == nil { + if _, ok := ftc.mutation.Int8(); !ok { return nil, errors.New("ent: missing required field \"int8\"") } - if ftc.int16 == nil { + if _, ok := ftc.mutation.Int16(); !ok { return nil, errors.New("ent: missing required field \"int16\"") } - if ftc.int32 == nil { + if _, ok := ftc.mutation.Int32(); !ok { return nil, errors.New("ent: missing required field \"int32\"") } - if ftc.int64 == nil { + if _, ok := ftc.mutation.Int64(); !ok { return nil, errors.New("ent: missing required field \"int64\"") } - if ftc.validate_optional_int32 != nil { - if err := fieldtype.ValidateOptionalInt32Validator(*ftc.validate_optional_int32); err != nil { + if v, ok := ftc.mutation.ValidateOptionalInt32(); ok { + if err := fieldtype.ValidateOptionalInt32Validator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"validate_optional_int32\": %v", err) } } - if ftc.state != nil { - if err := fieldtype.StateValidator(*ftc.state); err != nil { + if v, ok := ftc.mutation.State(); ok { + if err := fieldtype.StateValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"state\": %v", err) } } - return ftc.gremlinSave(ctx) + var ( + err error + node *FieldType + ) + if len(ftc.hooks) == 0 { + node, err = ftc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftc.mutation = mutation + node, err = ftc.gremlinSave(ctx) + return node, err + }) + for i := len(ftc.hooks); i > 0; i-- { + mut = ftc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -399,77 +400,77 @@ func (ftc *FieldTypeCreate) gremlinSave(ctx context.Context) (*FieldType, error) func (ftc *FieldTypeCreate) gremlin() *dsl.Traversal { v := g.AddV(fieldtype.Label) - if ftc.int != nil { - v.Property(dsl.Single, fieldtype.FieldInt, *ftc.int) + if value, ok := ftc.mutation.Int(); ok { + v.Property(dsl.Single, fieldtype.FieldInt, value) } - if ftc.int8 != nil { - v.Property(dsl.Single, fieldtype.FieldInt8, *ftc.int8) + if value, ok := ftc.mutation.Int8(); ok { + v.Property(dsl.Single, fieldtype.FieldInt8, value) } - if ftc.int16 != nil { - v.Property(dsl.Single, fieldtype.FieldInt16, *ftc.int16) + if value, ok := ftc.mutation.Int16(); ok { + v.Property(dsl.Single, fieldtype.FieldInt16, value) } - if ftc.int32 != nil { - v.Property(dsl.Single, fieldtype.FieldInt32, *ftc.int32) + if value, ok := ftc.mutation.Int32(); ok { + v.Property(dsl.Single, fieldtype.FieldInt32, value) } - if ftc.int64 != nil { - v.Property(dsl.Single, fieldtype.FieldInt64, *ftc.int64) + if value, ok := ftc.mutation.Int64(); ok { + v.Property(dsl.Single, fieldtype.FieldInt64, value) } - if ftc.optional_int != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt, *ftc.optional_int) + if value, ok := ftc.mutation.OptionalInt(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt, value) } - if ftc.optional_int8 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt8, *ftc.optional_int8) + if value, ok := ftc.mutation.OptionalInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt8, value) } - if ftc.optional_int16 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt16, *ftc.optional_int16) + if value, ok := ftc.mutation.OptionalInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt16, value) } - if ftc.optional_int32 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt32, *ftc.optional_int32) + if value, ok := ftc.mutation.OptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt32, value) } - if ftc.optional_int64 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt64, *ftc.optional_int64) + if value, ok := ftc.mutation.OptionalInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt64, value) } - if ftc.nillable_int != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt, *ftc.nillable_int) + if value, ok := ftc.mutation.NillableInt(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt, value) } - if ftc.nillable_int8 != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt8, *ftc.nillable_int8) + if value, ok := ftc.mutation.NillableInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt8, value) } - if ftc.nillable_int16 != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt16, *ftc.nillable_int16) + if value, ok := ftc.mutation.NillableInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt16, value) } - if ftc.nillable_int32 != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt32, *ftc.nillable_int32) + if value, ok := ftc.mutation.NillableInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt32, value) } - if ftc.nillable_int64 != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt64, *ftc.nillable_int64) + if value, ok := ftc.mutation.NillableInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt64, value) } - if ftc.validate_optional_int32 != nil { - v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, *ftc.validate_optional_int32) + if value, ok := ftc.mutation.ValidateOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, value) } - if ftc.optional_uint != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint, *ftc.optional_uint) + if value, ok := ftc.mutation.OptionalUint(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint, value) } - if ftc.optional_uint8 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint8, *ftc.optional_uint8) + if value, ok := ftc.mutation.OptionalUint8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint8, value) } - if ftc.optional_uint16 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint16, *ftc.optional_uint16) + if value, ok := ftc.mutation.OptionalUint16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint16, value) } - if ftc.optional_uint32 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint32, *ftc.optional_uint32) + if value, ok := ftc.mutation.OptionalUint32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint32, value) } - if ftc.optional_uint64 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint64, *ftc.optional_uint64) + if value, ok := ftc.mutation.OptionalUint64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint64, value) } - if ftc.state != nil { - v.Property(dsl.Single, fieldtype.FieldState, *ftc.state) + if value, ok := ftc.mutation.State(); ok { + v.Property(dsl.Single, fieldtype.FieldState, value) } - if ftc.optional_float != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat, *ftc.optional_float) + if value, ok := ftc.mutation.OptionalFloat(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat, value) } - if ftc.optional_float32 != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, *ftc.optional_float32) + if value, ok := ftc.mutation.OptionalFloat32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, value) } return v.ValueMap(true) } diff --git a/entc/integration/gremlin/ent/fieldtype_delete.go b/entc/integration/gremlin/ent/fieldtype_delete.go index 9995e86a3..4ed797aba 100644 --- a/entc/integration/gremlin/ent/fieldtype_delete.go +++ b/entc/integration/gremlin/ent/fieldtype_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // FieldTypeDelete is the builder for deleting a FieldType entity. type FieldTypeDelete struct { config + hooks []Hook + mutation *FieldTypeMutation predicates []predicate.FieldType } @@ -31,7 +34,30 @@ func (ftd *FieldTypeDelete) Where(ps ...predicate.FieldType) *FieldTypeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ftd *FieldTypeDelete) Exec(ctx context.Context) (int, error) { - return ftd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(ftd.hooks) == 0 { + affected, err = ftd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftd.mutation = mutation + affected, err = ftd.gremlinExec(ctx) + return affected, err + }) + for i := len(ftd.hooks); i > 0; i-- { + mut = ftd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/fieldtype_update.go b/entc/integration/gremlin/ent/fieldtype_update.go index f6331bb73..61a5ab3d4 100644 --- a/entc/integration/gremlin/ent/fieldtype_update.go +++ b/entc/integration/gremlin/ent/fieldtype_update.go @@ -21,73 +21,9 @@ import ( // FieldTypeUpdate is the builder for updating FieldType entities. type FieldTypeUpdate struct { config - int *int - addint *int - int8 *int8 - addint8 *int8 - int16 *int16 - addint16 *int16 - int32 *int32 - addint32 *int32 - int64 *int64 - addint64 *int64 - optional_int *int - addoptional_int *int - clearoptional_int bool - optional_int8 *int8 - addoptional_int8 *int8 - clearoptional_int8 bool - optional_int16 *int16 - addoptional_int16 *int16 - clearoptional_int16 bool - optional_int32 *int32 - addoptional_int32 *int32 - clearoptional_int32 bool - optional_int64 *int64 - addoptional_int64 *int64 - clearoptional_int64 bool - nillable_int *int - addnillable_int *int - clearnillable_int bool - nillable_int8 *int8 - addnillable_int8 *int8 - clearnillable_int8 bool - nillable_int16 *int16 - addnillable_int16 *int16 - clearnillable_int16 bool - nillable_int32 *int32 - addnillable_int32 *int32 - clearnillable_int32 bool - nillable_int64 *int64 - addnillable_int64 *int64 - clearnillable_int64 bool - validate_optional_int32 *int32 - addvalidate_optional_int32 *int32 - clearvalidate_optional_int32 bool - optional_uint *uint - addoptional_uint *uint - clearoptional_uint bool - optional_uint8 *uint8 - addoptional_uint8 *uint8 - clearoptional_uint8 bool - optional_uint16 *uint16 - addoptional_uint16 *uint16 - clearoptional_uint16 bool - optional_uint32 *uint32 - addoptional_uint32 *uint32 - clearoptional_uint32 bool - optional_uint64 *uint64 - addoptional_uint64 *uint64 - clearoptional_uint64 bool - state *fieldtype.State - clearstate bool - optional_float *float64 - addoptional_float *float64 - clearoptional_float bool - optional_float32 *float32 - addoptional_float32 *float32 - clearoptional_float32 bool - predicates []predicate.FieldType + hooks []Hook + mutation *FieldTypeMutation + predicates []predicate.FieldType } // Where adds a new predicate for the builder. @@ -98,93 +34,73 @@ func (ftu *FieldTypeUpdate) Where(ps ...predicate.FieldType) *FieldTypeUpdate { // SetInt sets the int field. func (ftu *FieldTypeUpdate) SetInt(i int) *FieldTypeUpdate { - ftu.int = &i - ftu.addint = nil + ftu.mutation.ResetInt() + ftu.mutation.SetInt(i) return ftu } // AddInt adds i to int. func (ftu *FieldTypeUpdate) AddInt(i int) *FieldTypeUpdate { - if ftu.addint == nil { - ftu.addint = &i - } else { - *ftu.addint += i - } + ftu.mutation.AddInt(i) return ftu } // SetInt8 sets the int8 field. func (ftu *FieldTypeUpdate) SetInt8(i int8) *FieldTypeUpdate { - ftu.int8 = &i - ftu.addint8 = nil + ftu.mutation.ResetInt8() + ftu.mutation.SetInt8(i) return ftu } // AddInt8 adds i to int8. func (ftu *FieldTypeUpdate) AddInt8(i int8) *FieldTypeUpdate { - if ftu.addint8 == nil { - ftu.addint8 = &i - } else { - *ftu.addint8 += i - } + ftu.mutation.AddInt8(i) return ftu } // SetInt16 sets the int16 field. func (ftu *FieldTypeUpdate) SetInt16(i int16) *FieldTypeUpdate { - ftu.int16 = &i - ftu.addint16 = nil + ftu.mutation.ResetInt16() + ftu.mutation.SetInt16(i) return ftu } // AddInt16 adds i to int16. func (ftu *FieldTypeUpdate) AddInt16(i int16) *FieldTypeUpdate { - if ftu.addint16 == nil { - ftu.addint16 = &i - } else { - *ftu.addint16 += i - } + ftu.mutation.AddInt16(i) return ftu } // SetInt32 sets the int32 field. func (ftu *FieldTypeUpdate) SetInt32(i int32) *FieldTypeUpdate { - ftu.int32 = &i - ftu.addint32 = nil + ftu.mutation.ResetInt32() + ftu.mutation.SetInt32(i) return ftu } // AddInt32 adds i to int32. func (ftu *FieldTypeUpdate) AddInt32(i int32) *FieldTypeUpdate { - if ftu.addint32 == nil { - ftu.addint32 = &i - } else { - *ftu.addint32 += i - } + ftu.mutation.AddInt32(i) return ftu } // SetInt64 sets the int64 field. func (ftu *FieldTypeUpdate) SetInt64(i int64) *FieldTypeUpdate { - ftu.int64 = &i - ftu.addint64 = nil + ftu.mutation.ResetInt64() + ftu.mutation.SetInt64(i) return ftu } // AddInt64 adds i to int64. func (ftu *FieldTypeUpdate) AddInt64(i int64) *FieldTypeUpdate { - if ftu.addint64 == nil { - ftu.addint64 = &i - } else { - *ftu.addint64 += i - } + ftu.mutation.AddInt64(i) return ftu } // SetOptionalInt sets the optional_int field. func (ftu *FieldTypeUpdate) SetOptionalInt(i int) *FieldTypeUpdate { - ftu.optional_int = &i - ftu.addoptional_int = nil + ftu.mutation.ResetOptionalInt() + ftu.mutation.SetOptionalInt(i) return ftu } @@ -198,25 +114,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt(i *int) *FieldTypeUpdate { // AddOptionalInt adds i to optional_int. func (ftu *FieldTypeUpdate) AddOptionalInt(i int) *FieldTypeUpdate { - if ftu.addoptional_int == nil { - ftu.addoptional_int = &i - } else { - *ftu.addoptional_int += i - } + ftu.mutation.AddOptionalInt(i) return ftu } // ClearOptionalInt clears the value of optional_int. func (ftu *FieldTypeUpdate) ClearOptionalInt() *FieldTypeUpdate { - ftu.optional_int = nil - ftu.clearoptional_int = true + ftu.mutation.ClearOptionalInt() return ftu } // SetOptionalInt8 sets the optional_int8 field. func (ftu *FieldTypeUpdate) SetOptionalInt8(i int8) *FieldTypeUpdate { - ftu.optional_int8 = &i - ftu.addoptional_int8 = nil + ftu.mutation.ResetOptionalInt8() + ftu.mutation.SetOptionalInt8(i) return ftu } @@ -230,25 +141,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt8(i *int8) *FieldTypeUpdate { // AddOptionalInt8 adds i to optional_int8. func (ftu *FieldTypeUpdate) AddOptionalInt8(i int8) *FieldTypeUpdate { - if ftu.addoptional_int8 == nil { - ftu.addoptional_int8 = &i - } else { - *ftu.addoptional_int8 += i - } + ftu.mutation.AddOptionalInt8(i) return ftu } // ClearOptionalInt8 clears the value of optional_int8. func (ftu *FieldTypeUpdate) ClearOptionalInt8() *FieldTypeUpdate { - ftu.optional_int8 = nil - ftu.clearoptional_int8 = true + ftu.mutation.ClearOptionalInt8() return ftu } // SetOptionalInt16 sets the optional_int16 field. func (ftu *FieldTypeUpdate) SetOptionalInt16(i int16) *FieldTypeUpdate { - ftu.optional_int16 = &i - ftu.addoptional_int16 = nil + ftu.mutation.ResetOptionalInt16() + ftu.mutation.SetOptionalInt16(i) return ftu } @@ -262,25 +168,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt16(i *int16) *FieldTypeUpdate // AddOptionalInt16 adds i to optional_int16. func (ftu *FieldTypeUpdate) AddOptionalInt16(i int16) *FieldTypeUpdate { - if ftu.addoptional_int16 == nil { - ftu.addoptional_int16 = &i - } else { - *ftu.addoptional_int16 += i - } + ftu.mutation.AddOptionalInt16(i) return ftu } // ClearOptionalInt16 clears the value of optional_int16. func (ftu *FieldTypeUpdate) ClearOptionalInt16() *FieldTypeUpdate { - ftu.optional_int16 = nil - ftu.clearoptional_int16 = true + ftu.mutation.ClearOptionalInt16() return ftu } // SetOptionalInt32 sets the optional_int32 field. func (ftu *FieldTypeUpdate) SetOptionalInt32(i int32) *FieldTypeUpdate { - ftu.optional_int32 = &i - ftu.addoptional_int32 = nil + ftu.mutation.ResetOptionalInt32() + ftu.mutation.SetOptionalInt32(i) return ftu } @@ -294,25 +195,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt32(i *int32) *FieldTypeUpdate // AddOptionalInt32 adds i to optional_int32. func (ftu *FieldTypeUpdate) AddOptionalInt32(i int32) *FieldTypeUpdate { - if ftu.addoptional_int32 == nil { - ftu.addoptional_int32 = &i - } else { - *ftu.addoptional_int32 += i - } + ftu.mutation.AddOptionalInt32(i) return ftu } // ClearOptionalInt32 clears the value of optional_int32. func (ftu *FieldTypeUpdate) ClearOptionalInt32() *FieldTypeUpdate { - ftu.optional_int32 = nil - ftu.clearoptional_int32 = true + ftu.mutation.ClearOptionalInt32() return ftu } // SetOptionalInt64 sets the optional_int64 field. func (ftu *FieldTypeUpdate) SetOptionalInt64(i int64) *FieldTypeUpdate { - ftu.optional_int64 = &i - ftu.addoptional_int64 = nil + ftu.mutation.ResetOptionalInt64() + ftu.mutation.SetOptionalInt64(i) return ftu } @@ -326,25 +222,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalInt64(i *int64) *FieldTypeUpdate // AddOptionalInt64 adds i to optional_int64. func (ftu *FieldTypeUpdate) AddOptionalInt64(i int64) *FieldTypeUpdate { - if ftu.addoptional_int64 == nil { - ftu.addoptional_int64 = &i - } else { - *ftu.addoptional_int64 += i - } + ftu.mutation.AddOptionalInt64(i) return ftu } // ClearOptionalInt64 clears the value of optional_int64. func (ftu *FieldTypeUpdate) ClearOptionalInt64() *FieldTypeUpdate { - ftu.optional_int64 = nil - ftu.clearoptional_int64 = true + ftu.mutation.ClearOptionalInt64() return ftu } // SetNillableInt sets the nillable_int field. func (ftu *FieldTypeUpdate) SetNillableInt(i int) *FieldTypeUpdate { - ftu.nillable_int = &i - ftu.addnillable_int = nil + ftu.mutation.ResetNillableInt() + ftu.mutation.SetNillableInt(i) return ftu } @@ -358,25 +249,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt(i *int) *FieldTypeUpdate { // AddNillableInt adds i to nillable_int. func (ftu *FieldTypeUpdate) AddNillableInt(i int) *FieldTypeUpdate { - if ftu.addnillable_int == nil { - ftu.addnillable_int = &i - } else { - *ftu.addnillable_int += i - } + ftu.mutation.AddNillableInt(i) return ftu } // ClearNillableInt clears the value of nillable_int. func (ftu *FieldTypeUpdate) ClearNillableInt() *FieldTypeUpdate { - ftu.nillable_int = nil - ftu.clearnillable_int = true + ftu.mutation.ClearNillableInt() return ftu } // SetNillableInt8 sets the nillable_int8 field. func (ftu *FieldTypeUpdate) SetNillableInt8(i int8) *FieldTypeUpdate { - ftu.nillable_int8 = &i - ftu.addnillable_int8 = nil + ftu.mutation.ResetNillableInt8() + ftu.mutation.SetNillableInt8(i) return ftu } @@ -390,25 +276,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt8(i *int8) *FieldTypeUpdate { // AddNillableInt8 adds i to nillable_int8. func (ftu *FieldTypeUpdate) AddNillableInt8(i int8) *FieldTypeUpdate { - if ftu.addnillable_int8 == nil { - ftu.addnillable_int8 = &i - } else { - *ftu.addnillable_int8 += i - } + ftu.mutation.AddNillableInt8(i) return ftu } // ClearNillableInt8 clears the value of nillable_int8. func (ftu *FieldTypeUpdate) ClearNillableInt8() *FieldTypeUpdate { - ftu.nillable_int8 = nil - ftu.clearnillable_int8 = true + ftu.mutation.ClearNillableInt8() return ftu } // SetNillableInt16 sets the nillable_int16 field. func (ftu *FieldTypeUpdate) SetNillableInt16(i int16) *FieldTypeUpdate { - ftu.nillable_int16 = &i - ftu.addnillable_int16 = nil + ftu.mutation.ResetNillableInt16() + ftu.mutation.SetNillableInt16(i) return ftu } @@ -422,25 +303,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt16(i *int16) *FieldTypeUpdate // AddNillableInt16 adds i to nillable_int16. func (ftu *FieldTypeUpdate) AddNillableInt16(i int16) *FieldTypeUpdate { - if ftu.addnillable_int16 == nil { - ftu.addnillable_int16 = &i - } else { - *ftu.addnillable_int16 += i - } + ftu.mutation.AddNillableInt16(i) return ftu } // ClearNillableInt16 clears the value of nillable_int16. func (ftu *FieldTypeUpdate) ClearNillableInt16() *FieldTypeUpdate { - ftu.nillable_int16 = nil - ftu.clearnillable_int16 = true + ftu.mutation.ClearNillableInt16() return ftu } // SetNillableInt32 sets the nillable_int32 field. func (ftu *FieldTypeUpdate) SetNillableInt32(i int32) *FieldTypeUpdate { - ftu.nillable_int32 = &i - ftu.addnillable_int32 = nil + ftu.mutation.ResetNillableInt32() + ftu.mutation.SetNillableInt32(i) return ftu } @@ -454,25 +330,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt32(i *int32) *FieldTypeUpdate // AddNillableInt32 adds i to nillable_int32. func (ftu *FieldTypeUpdate) AddNillableInt32(i int32) *FieldTypeUpdate { - if ftu.addnillable_int32 == nil { - ftu.addnillable_int32 = &i - } else { - *ftu.addnillable_int32 += i - } + ftu.mutation.AddNillableInt32(i) return ftu } // ClearNillableInt32 clears the value of nillable_int32. func (ftu *FieldTypeUpdate) ClearNillableInt32() *FieldTypeUpdate { - ftu.nillable_int32 = nil - ftu.clearnillable_int32 = true + ftu.mutation.ClearNillableInt32() return ftu } // SetNillableInt64 sets the nillable_int64 field. func (ftu *FieldTypeUpdate) SetNillableInt64(i int64) *FieldTypeUpdate { - ftu.nillable_int64 = &i - ftu.addnillable_int64 = nil + ftu.mutation.ResetNillableInt64() + ftu.mutation.SetNillableInt64(i) return ftu } @@ -486,25 +357,20 @@ func (ftu *FieldTypeUpdate) SetNillableNillableInt64(i *int64) *FieldTypeUpdate // AddNillableInt64 adds i to nillable_int64. func (ftu *FieldTypeUpdate) AddNillableInt64(i int64) *FieldTypeUpdate { - if ftu.addnillable_int64 == nil { - ftu.addnillable_int64 = &i - } else { - *ftu.addnillable_int64 += i - } + ftu.mutation.AddNillableInt64(i) return ftu } // ClearNillableInt64 clears the value of nillable_int64. func (ftu *FieldTypeUpdate) ClearNillableInt64() *FieldTypeUpdate { - ftu.nillable_int64 = nil - ftu.clearnillable_int64 = true + ftu.mutation.ClearNillableInt64() return ftu } // SetValidateOptionalInt32 sets the validate_optional_int32 field. func (ftu *FieldTypeUpdate) SetValidateOptionalInt32(i int32) *FieldTypeUpdate { - ftu.validate_optional_int32 = &i - ftu.addvalidate_optional_int32 = nil + ftu.mutation.ResetValidateOptionalInt32() + ftu.mutation.SetValidateOptionalInt32(i) return ftu } @@ -518,25 +384,20 @@ func (ftu *FieldTypeUpdate) SetNillableValidateOptionalInt32(i *int32) *FieldTyp // AddValidateOptionalInt32 adds i to validate_optional_int32. func (ftu *FieldTypeUpdate) AddValidateOptionalInt32(i int32) *FieldTypeUpdate { - if ftu.addvalidate_optional_int32 == nil { - ftu.addvalidate_optional_int32 = &i - } else { - *ftu.addvalidate_optional_int32 += i - } + ftu.mutation.AddValidateOptionalInt32(i) return ftu } // ClearValidateOptionalInt32 clears the value of validate_optional_int32. func (ftu *FieldTypeUpdate) ClearValidateOptionalInt32() *FieldTypeUpdate { - ftu.validate_optional_int32 = nil - ftu.clearvalidate_optional_int32 = true + ftu.mutation.ClearValidateOptionalInt32() return ftu } // SetOptionalUint sets the optional_uint field. func (ftu *FieldTypeUpdate) SetOptionalUint(u uint) *FieldTypeUpdate { - ftu.optional_uint = &u - ftu.addoptional_uint = nil + ftu.mutation.ResetOptionalUint() + ftu.mutation.SetOptionalUint(u) return ftu } @@ -550,25 +411,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint(u *uint) *FieldTypeUpdate { // AddOptionalUint adds u to optional_uint. func (ftu *FieldTypeUpdate) AddOptionalUint(u uint) *FieldTypeUpdate { - if ftu.addoptional_uint == nil { - ftu.addoptional_uint = &u - } else { - *ftu.addoptional_uint += u - } + ftu.mutation.AddOptionalUint(u) return ftu } // ClearOptionalUint clears the value of optional_uint. func (ftu *FieldTypeUpdate) ClearOptionalUint() *FieldTypeUpdate { - ftu.optional_uint = nil - ftu.clearoptional_uint = true + ftu.mutation.ClearOptionalUint() return ftu } // SetOptionalUint8 sets the optional_uint8 field. func (ftu *FieldTypeUpdate) SetOptionalUint8(u uint8) *FieldTypeUpdate { - ftu.optional_uint8 = &u - ftu.addoptional_uint8 = nil + ftu.mutation.ResetOptionalUint8() + ftu.mutation.SetOptionalUint8(u) return ftu } @@ -582,25 +438,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint8(u *uint8) *FieldTypeUpdate // AddOptionalUint8 adds u to optional_uint8. func (ftu *FieldTypeUpdate) AddOptionalUint8(u uint8) *FieldTypeUpdate { - if ftu.addoptional_uint8 == nil { - ftu.addoptional_uint8 = &u - } else { - *ftu.addoptional_uint8 += u - } + ftu.mutation.AddOptionalUint8(u) return ftu } // ClearOptionalUint8 clears the value of optional_uint8. func (ftu *FieldTypeUpdate) ClearOptionalUint8() *FieldTypeUpdate { - ftu.optional_uint8 = nil - ftu.clearoptional_uint8 = true + ftu.mutation.ClearOptionalUint8() return ftu } // SetOptionalUint16 sets the optional_uint16 field. func (ftu *FieldTypeUpdate) SetOptionalUint16(u uint16) *FieldTypeUpdate { - ftu.optional_uint16 = &u - ftu.addoptional_uint16 = nil + ftu.mutation.ResetOptionalUint16() + ftu.mutation.SetOptionalUint16(u) return ftu } @@ -614,25 +465,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint16(u *uint16) *FieldTypeUpdat // AddOptionalUint16 adds u to optional_uint16. func (ftu *FieldTypeUpdate) AddOptionalUint16(u uint16) *FieldTypeUpdate { - if ftu.addoptional_uint16 == nil { - ftu.addoptional_uint16 = &u - } else { - *ftu.addoptional_uint16 += u - } + ftu.mutation.AddOptionalUint16(u) return ftu } // ClearOptionalUint16 clears the value of optional_uint16. func (ftu *FieldTypeUpdate) ClearOptionalUint16() *FieldTypeUpdate { - ftu.optional_uint16 = nil - ftu.clearoptional_uint16 = true + ftu.mutation.ClearOptionalUint16() return ftu } // SetOptionalUint32 sets the optional_uint32 field. func (ftu *FieldTypeUpdate) SetOptionalUint32(u uint32) *FieldTypeUpdate { - ftu.optional_uint32 = &u - ftu.addoptional_uint32 = nil + ftu.mutation.ResetOptionalUint32() + ftu.mutation.SetOptionalUint32(u) return ftu } @@ -646,25 +492,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint32(u *uint32) *FieldTypeUpdat // AddOptionalUint32 adds u to optional_uint32. func (ftu *FieldTypeUpdate) AddOptionalUint32(u uint32) *FieldTypeUpdate { - if ftu.addoptional_uint32 == nil { - ftu.addoptional_uint32 = &u - } else { - *ftu.addoptional_uint32 += u - } + ftu.mutation.AddOptionalUint32(u) return ftu } // ClearOptionalUint32 clears the value of optional_uint32. func (ftu *FieldTypeUpdate) ClearOptionalUint32() *FieldTypeUpdate { - ftu.optional_uint32 = nil - ftu.clearoptional_uint32 = true + ftu.mutation.ClearOptionalUint32() return ftu } // SetOptionalUint64 sets the optional_uint64 field. func (ftu *FieldTypeUpdate) SetOptionalUint64(u uint64) *FieldTypeUpdate { - ftu.optional_uint64 = &u - ftu.addoptional_uint64 = nil + ftu.mutation.ResetOptionalUint64() + ftu.mutation.SetOptionalUint64(u) return ftu } @@ -678,24 +519,19 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalUint64(u *uint64) *FieldTypeUpdat // AddOptionalUint64 adds u to optional_uint64. func (ftu *FieldTypeUpdate) AddOptionalUint64(u uint64) *FieldTypeUpdate { - if ftu.addoptional_uint64 == nil { - ftu.addoptional_uint64 = &u - } else { - *ftu.addoptional_uint64 += u - } + ftu.mutation.AddOptionalUint64(u) return ftu } // ClearOptionalUint64 clears the value of optional_uint64. func (ftu *FieldTypeUpdate) ClearOptionalUint64() *FieldTypeUpdate { - ftu.optional_uint64 = nil - ftu.clearoptional_uint64 = true + ftu.mutation.ClearOptionalUint64() return ftu } // SetState sets the state field. func (ftu *FieldTypeUpdate) SetState(f fieldtype.State) *FieldTypeUpdate { - ftu.state = &f + ftu.mutation.SetState(f) return ftu } @@ -709,15 +545,14 @@ func (ftu *FieldTypeUpdate) SetNillableState(f *fieldtype.State) *FieldTypeUpdat // ClearState clears the value of state. func (ftu *FieldTypeUpdate) ClearState() *FieldTypeUpdate { - ftu.state = nil - ftu.clearstate = true + ftu.mutation.ClearState() return ftu } // SetOptionalFloat sets the optional_float field. func (ftu *FieldTypeUpdate) SetOptionalFloat(f float64) *FieldTypeUpdate { - ftu.optional_float = &f - ftu.addoptional_float = nil + ftu.mutation.ResetOptionalFloat() + ftu.mutation.SetOptionalFloat(f) return ftu } @@ -731,25 +566,20 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalFloat(f *float64) *FieldTypeUpdat // AddOptionalFloat adds f to optional_float. func (ftu *FieldTypeUpdate) AddOptionalFloat(f float64) *FieldTypeUpdate { - if ftu.addoptional_float == nil { - ftu.addoptional_float = &f - } else { - *ftu.addoptional_float += f - } + ftu.mutation.AddOptionalFloat(f) return ftu } // ClearOptionalFloat clears the value of optional_float. func (ftu *FieldTypeUpdate) ClearOptionalFloat() *FieldTypeUpdate { - ftu.optional_float = nil - ftu.clearoptional_float = true + ftu.mutation.ClearOptionalFloat() return ftu } // SetOptionalFloat32 sets the optional_float32 field. func (ftu *FieldTypeUpdate) SetOptionalFloat32(f float32) *FieldTypeUpdate { - ftu.optional_float32 = &f - ftu.addoptional_float32 = nil + ftu.mutation.ResetOptionalFloat32() + ftu.mutation.SetOptionalFloat32(f) return ftu } @@ -763,34 +593,52 @@ func (ftu *FieldTypeUpdate) SetNillableOptionalFloat32(f *float32) *FieldTypeUpd // AddOptionalFloat32 adds f to optional_float32. func (ftu *FieldTypeUpdate) AddOptionalFloat32(f float32) *FieldTypeUpdate { - if ftu.addoptional_float32 == nil { - ftu.addoptional_float32 = &f - } else { - *ftu.addoptional_float32 += f - } + ftu.mutation.AddOptionalFloat32(f) return ftu } // ClearOptionalFloat32 clears the value of optional_float32. func (ftu *FieldTypeUpdate) ClearOptionalFloat32() *FieldTypeUpdate { - ftu.optional_float32 = nil - ftu.clearoptional_float32 = true + ftu.mutation.ClearOptionalFloat32() return ftu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (ftu *FieldTypeUpdate) Save(ctx context.Context) (int, error) { - if ftu.validate_optional_int32 != nil { - if err := fieldtype.ValidateOptionalInt32Validator(*ftu.validate_optional_int32); err != nil { + if v, ok := ftu.mutation.ValidateOptionalInt32(); ok { + if err := fieldtype.ValidateOptionalInt32Validator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"validate_optional_int32\": %v", err) } } - if ftu.state != nil { - if err := fieldtype.StateValidator(*ftu.state); err != nil { + if v, ok := ftu.mutation.State(); ok { + if err := fieldtype.StateValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"state\": %v", err) } } - return ftu.gremlinSave(ctx) + var ( + err error + affected int + ) + if len(ftu.hooks) == 0 { + affected, err = ftu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftu.mutation = mutation + affected, err = ftu.gremlinSave(ctx) + return affected, err + }) + for i := len(ftu.hooks); i > 0; i-- { + mut = ftu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -835,203 +683,203 @@ func (ftu *FieldTypeUpdate) gremlin() *dsl.Traversal { var ( trs []*dsl.Traversal ) - if value := ftu.int; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt, *value) + if value, ok := ftu.mutation.Int(); ok { + v.Property(dsl.Single, fieldtype.FieldInt, value) } - if value := ftu.addint; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt, __.Union(__.Values(fieldtype.FieldInt), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedInt(); ok { + v.Property(dsl.Single, fieldtype.FieldInt, __.Union(__.Values(fieldtype.FieldInt), __.Constant(value)).Sum()) } - if value := ftu.int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt8, *value) + if value, ok := ftu.mutation.Int8(); ok { + v.Property(dsl.Single, fieldtype.FieldInt8, value) } - if value := ftu.addint8; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt8, __.Union(__.Values(fieldtype.FieldInt8), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldInt8, __.Union(__.Values(fieldtype.FieldInt8), __.Constant(value)).Sum()) } - if value := ftu.int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt16, *value) + if value, ok := ftu.mutation.Int16(); ok { + v.Property(dsl.Single, fieldtype.FieldInt16, value) } - if value := ftu.addint16; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt16, __.Union(__.Values(fieldtype.FieldInt16), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldInt16, __.Union(__.Values(fieldtype.FieldInt16), __.Constant(value)).Sum()) } - if value := ftu.int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt32, *value) + if value, ok := ftu.mutation.Int32(); ok { + v.Property(dsl.Single, fieldtype.FieldInt32, value) } - if value := ftu.addint32; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt32, __.Union(__.Values(fieldtype.FieldInt32), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldInt32, __.Union(__.Values(fieldtype.FieldInt32), __.Constant(value)).Sum()) } - if value := ftu.int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt64, *value) + if value, ok := ftu.mutation.Int64(); ok { + v.Property(dsl.Single, fieldtype.FieldInt64, value) } - if value := ftu.addint64; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt64, __.Union(__.Values(fieldtype.FieldInt64), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldInt64, __.Union(__.Values(fieldtype.FieldInt64), __.Constant(value)).Sum()) } - if value := ftu.optional_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt, *value) + if value, ok := ftu.mutation.OptionalInt(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt, value) } - if value := ftu.addoptional_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt, __.Union(__.Values(fieldtype.FieldOptionalInt), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalInt(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt, __.Union(__.Values(fieldtype.FieldOptionalInt), __.Constant(value)).Sum()) } - if value := ftu.optional_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt8, *value) + if value, ok := ftu.mutation.OptionalInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt8, value) } - if value := ftu.addoptional_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt8, __.Union(__.Values(fieldtype.FieldOptionalInt8), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt8, __.Union(__.Values(fieldtype.FieldOptionalInt8), __.Constant(value)).Sum()) } - if value := ftu.optional_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt16, *value) + if value, ok := ftu.mutation.OptionalInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt16, value) } - if value := ftu.addoptional_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt16, __.Union(__.Values(fieldtype.FieldOptionalInt16), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt16, __.Union(__.Values(fieldtype.FieldOptionalInt16), __.Constant(value)).Sum()) } - if value := ftu.optional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt32, *value) + if value, ok := ftu.mutation.OptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt32, value) } - if value := ftu.addoptional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt32, __.Union(__.Values(fieldtype.FieldOptionalInt32), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt32, __.Union(__.Values(fieldtype.FieldOptionalInt32), __.Constant(value)).Sum()) } - if value := ftu.optional_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt64, *value) + if value, ok := ftu.mutation.OptionalInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt64, value) } - if value := ftu.addoptional_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt64, __.Union(__.Values(fieldtype.FieldOptionalInt64), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt64, __.Union(__.Values(fieldtype.FieldOptionalInt64), __.Constant(value)).Sum()) } - if value := ftu.nillable_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt, *value) + if value, ok := ftu.mutation.NillableInt(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt, value) } - if value := ftu.addnillable_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt, __.Union(__.Values(fieldtype.FieldNillableInt), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedNillableInt(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt, __.Union(__.Values(fieldtype.FieldNillableInt), __.Constant(value)).Sum()) } - if value := ftu.nillable_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt8, *value) + if value, ok := ftu.mutation.NillableInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt8, value) } - if value := ftu.addnillable_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt8, __.Union(__.Values(fieldtype.FieldNillableInt8), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedNillableInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt8, __.Union(__.Values(fieldtype.FieldNillableInt8), __.Constant(value)).Sum()) } - if value := ftu.nillable_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt16, *value) + if value, ok := ftu.mutation.NillableInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt16, value) } - if value := ftu.addnillable_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt16, __.Union(__.Values(fieldtype.FieldNillableInt16), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedNillableInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt16, __.Union(__.Values(fieldtype.FieldNillableInt16), __.Constant(value)).Sum()) } - if value := ftu.nillable_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt32, *value) + if value, ok := ftu.mutation.NillableInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt32, value) } - if value := ftu.addnillable_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt32, __.Union(__.Values(fieldtype.FieldNillableInt32), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedNillableInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt32, __.Union(__.Values(fieldtype.FieldNillableInt32), __.Constant(value)).Sum()) } - if value := ftu.nillable_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt64, *value) + if value, ok := ftu.mutation.NillableInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt64, value) } - if value := ftu.addnillable_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt64, __.Union(__.Values(fieldtype.FieldNillableInt64), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedNillableInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt64, __.Union(__.Values(fieldtype.FieldNillableInt64), __.Constant(value)).Sum()) } - if value := ftu.validate_optional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, *value) + if value, ok := ftu.mutation.ValidateOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, value) } - if value := ftu.addvalidate_optional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, __.Union(__.Values(fieldtype.FieldValidateOptionalInt32), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedValidateOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, __.Union(__.Values(fieldtype.FieldValidateOptionalInt32), __.Constant(value)).Sum()) } - if value := ftu.optional_uint; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint, *value) + if value, ok := ftu.mutation.OptionalUint(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint, value) } - if value := ftu.addoptional_uint; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint, __.Union(__.Values(fieldtype.FieldOptionalUint), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalUint(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint, __.Union(__.Values(fieldtype.FieldOptionalUint), __.Constant(value)).Sum()) } - if value := ftu.optional_uint8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint8, *value) + if value, ok := ftu.mutation.OptionalUint8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint8, value) } - if value := ftu.addoptional_uint8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint8, __.Union(__.Values(fieldtype.FieldOptionalUint8), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalUint8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint8, __.Union(__.Values(fieldtype.FieldOptionalUint8), __.Constant(value)).Sum()) } - if value := ftu.optional_uint16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint16, *value) + if value, ok := ftu.mutation.OptionalUint16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint16, value) } - if value := ftu.addoptional_uint16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint16, __.Union(__.Values(fieldtype.FieldOptionalUint16), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalUint16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint16, __.Union(__.Values(fieldtype.FieldOptionalUint16), __.Constant(value)).Sum()) } - if value := ftu.optional_uint32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint32, *value) + if value, ok := ftu.mutation.OptionalUint32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint32, value) } - if value := ftu.addoptional_uint32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint32, __.Union(__.Values(fieldtype.FieldOptionalUint32), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalUint32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint32, __.Union(__.Values(fieldtype.FieldOptionalUint32), __.Constant(value)).Sum()) } - if value := ftu.optional_uint64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint64, *value) + if value, ok := ftu.mutation.OptionalUint64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint64, value) } - if value := ftu.addoptional_uint64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint64, __.Union(__.Values(fieldtype.FieldOptionalUint64), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalUint64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint64, __.Union(__.Values(fieldtype.FieldOptionalUint64), __.Constant(value)).Sum()) } - if value := ftu.state; value != nil { - v.Property(dsl.Single, fieldtype.FieldState, *value) + if value, ok := ftu.mutation.State(); ok { + v.Property(dsl.Single, fieldtype.FieldState, value) } - if value := ftu.optional_float; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat, *value) + if value, ok := ftu.mutation.OptionalFloat(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat, value) } - if value := ftu.addoptional_float; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat, __.Union(__.Values(fieldtype.FieldOptionalFloat), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalFloat(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat, __.Union(__.Values(fieldtype.FieldOptionalFloat), __.Constant(value)).Sum()) } - if value := ftu.optional_float32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, *value) + if value, ok := ftu.mutation.OptionalFloat32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, value) } - if value := ftu.addoptional_float32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, __.Union(__.Values(fieldtype.FieldOptionalFloat32), __.Constant(*value)).Sum()) + if value, ok := ftu.mutation.AddedOptionalFloat32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, __.Union(__.Values(fieldtype.FieldOptionalFloat32), __.Constant(value)).Sum()) } var properties []interface{} - if ftu.clearoptional_int { + if ftu.mutation.OptionalIntCleared() { properties = append(properties, fieldtype.FieldOptionalInt) } - if ftu.clearoptional_int8 { + if ftu.mutation.OptionalInt8Cleared() { properties = append(properties, fieldtype.FieldOptionalInt8) } - if ftu.clearoptional_int16 { + if ftu.mutation.OptionalInt16Cleared() { properties = append(properties, fieldtype.FieldOptionalInt16) } - if ftu.clearoptional_int32 { + if ftu.mutation.OptionalInt32Cleared() { properties = append(properties, fieldtype.FieldOptionalInt32) } - if ftu.clearoptional_int64 { + if ftu.mutation.OptionalInt64Cleared() { properties = append(properties, fieldtype.FieldOptionalInt64) } - if ftu.clearnillable_int { + if ftu.mutation.NillableIntCleared() { properties = append(properties, fieldtype.FieldNillableInt) } - if ftu.clearnillable_int8 { + if ftu.mutation.NillableInt8Cleared() { properties = append(properties, fieldtype.FieldNillableInt8) } - if ftu.clearnillable_int16 { + if ftu.mutation.NillableInt16Cleared() { properties = append(properties, fieldtype.FieldNillableInt16) } - if ftu.clearnillable_int32 { + if ftu.mutation.NillableInt32Cleared() { properties = append(properties, fieldtype.FieldNillableInt32) } - if ftu.clearnillable_int64 { + if ftu.mutation.NillableInt64Cleared() { properties = append(properties, fieldtype.FieldNillableInt64) } - if ftu.clearvalidate_optional_int32 { + if ftu.mutation.ValidateOptionalInt32Cleared() { properties = append(properties, fieldtype.FieldValidateOptionalInt32) } - if ftu.clearoptional_uint { + if ftu.mutation.OptionalUintCleared() { properties = append(properties, fieldtype.FieldOptionalUint) } - if ftu.clearoptional_uint8 { + if ftu.mutation.OptionalUint8Cleared() { properties = append(properties, fieldtype.FieldOptionalUint8) } - if ftu.clearoptional_uint16 { + if ftu.mutation.OptionalUint16Cleared() { properties = append(properties, fieldtype.FieldOptionalUint16) } - if ftu.clearoptional_uint32 { + if ftu.mutation.OptionalUint32Cleared() { properties = append(properties, fieldtype.FieldOptionalUint32) } - if ftu.clearoptional_uint64 { + if ftu.mutation.OptionalUint64Cleared() { properties = append(properties, fieldtype.FieldOptionalUint64) } - if ftu.clearstate { + if ftu.mutation.StateCleared() { properties = append(properties, fieldtype.FieldState) } - if ftu.clearoptional_float { + if ftu.mutation.OptionalFloatCleared() { properties = append(properties, fieldtype.FieldOptionalFloat) } - if ftu.clearoptional_float32 { + if ftu.mutation.OptionalFloat32Cleared() { properties = append(properties, fieldtype.FieldOptionalFloat32) } if len(properties) > 0 { @@ -1045,164 +893,79 @@ func (ftu *FieldTypeUpdate) gremlin() *dsl.Traversal { // FieldTypeUpdateOne is the builder for updating a single FieldType entity. type FieldTypeUpdateOne struct { config - id string - int *int - addint *int - int8 *int8 - addint8 *int8 - int16 *int16 - addint16 *int16 - int32 *int32 - addint32 *int32 - int64 *int64 - addint64 *int64 - optional_int *int - addoptional_int *int - clearoptional_int bool - optional_int8 *int8 - addoptional_int8 *int8 - clearoptional_int8 bool - optional_int16 *int16 - addoptional_int16 *int16 - clearoptional_int16 bool - optional_int32 *int32 - addoptional_int32 *int32 - clearoptional_int32 bool - optional_int64 *int64 - addoptional_int64 *int64 - clearoptional_int64 bool - nillable_int *int - addnillable_int *int - clearnillable_int bool - nillable_int8 *int8 - addnillable_int8 *int8 - clearnillable_int8 bool - nillable_int16 *int16 - addnillable_int16 *int16 - clearnillable_int16 bool - nillable_int32 *int32 - addnillable_int32 *int32 - clearnillable_int32 bool - nillable_int64 *int64 - addnillable_int64 *int64 - clearnillable_int64 bool - validate_optional_int32 *int32 - addvalidate_optional_int32 *int32 - clearvalidate_optional_int32 bool - optional_uint *uint - addoptional_uint *uint - clearoptional_uint bool - optional_uint8 *uint8 - addoptional_uint8 *uint8 - clearoptional_uint8 bool - optional_uint16 *uint16 - addoptional_uint16 *uint16 - clearoptional_uint16 bool - optional_uint32 *uint32 - addoptional_uint32 *uint32 - clearoptional_uint32 bool - optional_uint64 *uint64 - addoptional_uint64 *uint64 - clearoptional_uint64 bool - state *fieldtype.State - clearstate bool - optional_float *float64 - addoptional_float *float64 - clearoptional_float bool - optional_float32 *float32 - addoptional_float32 *float32 - clearoptional_float32 bool + hooks []Hook + mutation *FieldTypeMutation } // SetInt sets the int field. func (ftuo *FieldTypeUpdateOne) SetInt(i int) *FieldTypeUpdateOne { - ftuo.int = &i - ftuo.addint = nil + ftuo.mutation.ResetInt() + ftuo.mutation.SetInt(i) return ftuo } // AddInt adds i to int. func (ftuo *FieldTypeUpdateOne) AddInt(i int) *FieldTypeUpdateOne { - if ftuo.addint == nil { - ftuo.addint = &i - } else { - *ftuo.addint += i - } + ftuo.mutation.AddInt(i) return ftuo } // SetInt8 sets the int8 field. func (ftuo *FieldTypeUpdateOne) SetInt8(i int8) *FieldTypeUpdateOne { - ftuo.int8 = &i - ftuo.addint8 = nil + ftuo.mutation.ResetInt8() + ftuo.mutation.SetInt8(i) return ftuo } // AddInt8 adds i to int8. func (ftuo *FieldTypeUpdateOne) AddInt8(i int8) *FieldTypeUpdateOne { - if ftuo.addint8 == nil { - ftuo.addint8 = &i - } else { - *ftuo.addint8 += i - } + ftuo.mutation.AddInt8(i) return ftuo } // SetInt16 sets the int16 field. func (ftuo *FieldTypeUpdateOne) SetInt16(i int16) *FieldTypeUpdateOne { - ftuo.int16 = &i - ftuo.addint16 = nil + ftuo.mutation.ResetInt16() + ftuo.mutation.SetInt16(i) return ftuo } // AddInt16 adds i to int16. func (ftuo *FieldTypeUpdateOne) AddInt16(i int16) *FieldTypeUpdateOne { - if ftuo.addint16 == nil { - ftuo.addint16 = &i - } else { - *ftuo.addint16 += i - } + ftuo.mutation.AddInt16(i) return ftuo } // SetInt32 sets the int32 field. func (ftuo *FieldTypeUpdateOne) SetInt32(i int32) *FieldTypeUpdateOne { - ftuo.int32 = &i - ftuo.addint32 = nil + ftuo.mutation.ResetInt32() + ftuo.mutation.SetInt32(i) return ftuo } // AddInt32 adds i to int32. func (ftuo *FieldTypeUpdateOne) AddInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addint32 == nil { - ftuo.addint32 = &i - } else { - *ftuo.addint32 += i - } + ftuo.mutation.AddInt32(i) return ftuo } // SetInt64 sets the int64 field. func (ftuo *FieldTypeUpdateOne) SetInt64(i int64) *FieldTypeUpdateOne { - ftuo.int64 = &i - ftuo.addint64 = nil + ftuo.mutation.ResetInt64() + ftuo.mutation.SetInt64(i) return ftuo } // AddInt64 adds i to int64. func (ftuo *FieldTypeUpdateOne) AddInt64(i int64) *FieldTypeUpdateOne { - if ftuo.addint64 == nil { - ftuo.addint64 = &i - } else { - *ftuo.addint64 += i - } + ftuo.mutation.AddInt64(i) return ftuo } // SetOptionalInt sets the optional_int field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt(i int) *FieldTypeUpdateOne { - ftuo.optional_int = &i - ftuo.addoptional_int = nil + ftuo.mutation.ResetOptionalInt() + ftuo.mutation.SetOptionalInt(i) return ftuo } @@ -1216,25 +979,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt(i *int) *FieldTypeUpdateO // AddOptionalInt adds i to optional_int. func (ftuo *FieldTypeUpdateOne) AddOptionalInt(i int) *FieldTypeUpdateOne { - if ftuo.addoptional_int == nil { - ftuo.addoptional_int = &i - } else { - *ftuo.addoptional_int += i - } + ftuo.mutation.AddOptionalInt(i) return ftuo } // ClearOptionalInt clears the value of optional_int. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt() *FieldTypeUpdateOne { - ftuo.optional_int = nil - ftuo.clearoptional_int = true + ftuo.mutation.ClearOptionalInt() return ftuo } // SetOptionalInt8 sets the optional_int8 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt8(i int8) *FieldTypeUpdateOne { - ftuo.optional_int8 = &i - ftuo.addoptional_int8 = nil + ftuo.mutation.ResetOptionalInt8() + ftuo.mutation.SetOptionalInt8(i) return ftuo } @@ -1248,25 +1006,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt8(i *int8) *FieldTypeUpdat // AddOptionalInt8 adds i to optional_int8. func (ftuo *FieldTypeUpdateOne) AddOptionalInt8(i int8) *FieldTypeUpdateOne { - if ftuo.addoptional_int8 == nil { - ftuo.addoptional_int8 = &i - } else { - *ftuo.addoptional_int8 += i - } + ftuo.mutation.AddOptionalInt8(i) return ftuo } // ClearOptionalInt8 clears the value of optional_int8. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt8() *FieldTypeUpdateOne { - ftuo.optional_int8 = nil - ftuo.clearoptional_int8 = true + ftuo.mutation.ClearOptionalInt8() return ftuo } // SetOptionalInt16 sets the optional_int16 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt16(i int16) *FieldTypeUpdateOne { - ftuo.optional_int16 = &i - ftuo.addoptional_int16 = nil + ftuo.mutation.ResetOptionalInt16() + ftuo.mutation.SetOptionalInt16(i) return ftuo } @@ -1280,25 +1033,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt16(i *int16) *FieldTypeUpd // AddOptionalInt16 adds i to optional_int16. func (ftuo *FieldTypeUpdateOne) AddOptionalInt16(i int16) *FieldTypeUpdateOne { - if ftuo.addoptional_int16 == nil { - ftuo.addoptional_int16 = &i - } else { - *ftuo.addoptional_int16 += i - } + ftuo.mutation.AddOptionalInt16(i) return ftuo } // ClearOptionalInt16 clears the value of optional_int16. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt16() *FieldTypeUpdateOne { - ftuo.optional_int16 = nil - ftuo.clearoptional_int16 = true + ftuo.mutation.ClearOptionalInt16() return ftuo } // SetOptionalInt32 sets the optional_int32 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt32(i int32) *FieldTypeUpdateOne { - ftuo.optional_int32 = &i - ftuo.addoptional_int32 = nil + ftuo.mutation.ResetOptionalInt32() + ftuo.mutation.SetOptionalInt32(i) return ftuo } @@ -1312,25 +1060,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt32(i *int32) *FieldTypeUpd // AddOptionalInt32 adds i to optional_int32. func (ftuo *FieldTypeUpdateOne) AddOptionalInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addoptional_int32 == nil { - ftuo.addoptional_int32 = &i - } else { - *ftuo.addoptional_int32 += i - } + ftuo.mutation.AddOptionalInt32(i) return ftuo } // ClearOptionalInt32 clears the value of optional_int32. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt32() *FieldTypeUpdateOne { - ftuo.optional_int32 = nil - ftuo.clearoptional_int32 = true + ftuo.mutation.ClearOptionalInt32() return ftuo } // SetOptionalInt64 sets the optional_int64 field. func (ftuo *FieldTypeUpdateOne) SetOptionalInt64(i int64) *FieldTypeUpdateOne { - ftuo.optional_int64 = &i - ftuo.addoptional_int64 = nil + ftuo.mutation.ResetOptionalInt64() + ftuo.mutation.SetOptionalInt64(i) return ftuo } @@ -1344,25 +1087,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalInt64(i *int64) *FieldTypeUpd // AddOptionalInt64 adds i to optional_int64. func (ftuo *FieldTypeUpdateOne) AddOptionalInt64(i int64) *FieldTypeUpdateOne { - if ftuo.addoptional_int64 == nil { - ftuo.addoptional_int64 = &i - } else { - *ftuo.addoptional_int64 += i - } + ftuo.mutation.AddOptionalInt64(i) return ftuo } // ClearOptionalInt64 clears the value of optional_int64. func (ftuo *FieldTypeUpdateOne) ClearOptionalInt64() *FieldTypeUpdateOne { - ftuo.optional_int64 = nil - ftuo.clearoptional_int64 = true + ftuo.mutation.ClearOptionalInt64() return ftuo } // SetNillableInt sets the nillable_int field. func (ftuo *FieldTypeUpdateOne) SetNillableInt(i int) *FieldTypeUpdateOne { - ftuo.nillable_int = &i - ftuo.addnillable_int = nil + ftuo.mutation.ResetNillableInt() + ftuo.mutation.SetNillableInt(i) return ftuo } @@ -1376,25 +1114,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt(i *int) *FieldTypeUpdateO // AddNillableInt adds i to nillable_int. func (ftuo *FieldTypeUpdateOne) AddNillableInt(i int) *FieldTypeUpdateOne { - if ftuo.addnillable_int == nil { - ftuo.addnillable_int = &i - } else { - *ftuo.addnillable_int += i - } + ftuo.mutation.AddNillableInt(i) return ftuo } // ClearNillableInt clears the value of nillable_int. func (ftuo *FieldTypeUpdateOne) ClearNillableInt() *FieldTypeUpdateOne { - ftuo.nillable_int = nil - ftuo.clearnillable_int = true + ftuo.mutation.ClearNillableInt() return ftuo } // SetNillableInt8 sets the nillable_int8 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt8(i int8) *FieldTypeUpdateOne { - ftuo.nillable_int8 = &i - ftuo.addnillable_int8 = nil + ftuo.mutation.ResetNillableInt8() + ftuo.mutation.SetNillableInt8(i) return ftuo } @@ -1408,25 +1141,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt8(i *int8) *FieldTypeUpdat // AddNillableInt8 adds i to nillable_int8. func (ftuo *FieldTypeUpdateOne) AddNillableInt8(i int8) *FieldTypeUpdateOne { - if ftuo.addnillable_int8 == nil { - ftuo.addnillable_int8 = &i - } else { - *ftuo.addnillable_int8 += i - } + ftuo.mutation.AddNillableInt8(i) return ftuo } // ClearNillableInt8 clears the value of nillable_int8. func (ftuo *FieldTypeUpdateOne) ClearNillableInt8() *FieldTypeUpdateOne { - ftuo.nillable_int8 = nil - ftuo.clearnillable_int8 = true + ftuo.mutation.ClearNillableInt8() return ftuo } // SetNillableInt16 sets the nillable_int16 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt16(i int16) *FieldTypeUpdateOne { - ftuo.nillable_int16 = &i - ftuo.addnillable_int16 = nil + ftuo.mutation.ResetNillableInt16() + ftuo.mutation.SetNillableInt16(i) return ftuo } @@ -1440,25 +1168,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt16(i *int16) *FieldTypeUpd // AddNillableInt16 adds i to nillable_int16. func (ftuo *FieldTypeUpdateOne) AddNillableInt16(i int16) *FieldTypeUpdateOne { - if ftuo.addnillable_int16 == nil { - ftuo.addnillable_int16 = &i - } else { - *ftuo.addnillable_int16 += i - } + ftuo.mutation.AddNillableInt16(i) return ftuo } // ClearNillableInt16 clears the value of nillable_int16. func (ftuo *FieldTypeUpdateOne) ClearNillableInt16() *FieldTypeUpdateOne { - ftuo.nillable_int16 = nil - ftuo.clearnillable_int16 = true + ftuo.mutation.ClearNillableInt16() return ftuo } // SetNillableInt32 sets the nillable_int32 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt32(i int32) *FieldTypeUpdateOne { - ftuo.nillable_int32 = &i - ftuo.addnillable_int32 = nil + ftuo.mutation.ResetNillableInt32() + ftuo.mutation.SetNillableInt32(i) return ftuo } @@ -1472,25 +1195,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt32(i *int32) *FieldTypeUpd // AddNillableInt32 adds i to nillable_int32. func (ftuo *FieldTypeUpdateOne) AddNillableInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addnillable_int32 == nil { - ftuo.addnillable_int32 = &i - } else { - *ftuo.addnillable_int32 += i - } + ftuo.mutation.AddNillableInt32(i) return ftuo } // ClearNillableInt32 clears the value of nillable_int32. func (ftuo *FieldTypeUpdateOne) ClearNillableInt32() *FieldTypeUpdateOne { - ftuo.nillable_int32 = nil - ftuo.clearnillable_int32 = true + ftuo.mutation.ClearNillableInt32() return ftuo } // SetNillableInt64 sets the nillable_int64 field. func (ftuo *FieldTypeUpdateOne) SetNillableInt64(i int64) *FieldTypeUpdateOne { - ftuo.nillable_int64 = &i - ftuo.addnillable_int64 = nil + ftuo.mutation.ResetNillableInt64() + ftuo.mutation.SetNillableInt64(i) return ftuo } @@ -1504,25 +1222,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableNillableInt64(i *int64) *FieldTypeUpd // AddNillableInt64 adds i to nillable_int64. func (ftuo *FieldTypeUpdateOne) AddNillableInt64(i int64) *FieldTypeUpdateOne { - if ftuo.addnillable_int64 == nil { - ftuo.addnillable_int64 = &i - } else { - *ftuo.addnillable_int64 += i - } + ftuo.mutation.AddNillableInt64(i) return ftuo } // ClearNillableInt64 clears the value of nillable_int64. func (ftuo *FieldTypeUpdateOne) ClearNillableInt64() *FieldTypeUpdateOne { - ftuo.nillable_int64 = nil - ftuo.clearnillable_int64 = true + ftuo.mutation.ClearNillableInt64() return ftuo } // SetValidateOptionalInt32 sets the validate_optional_int32 field. func (ftuo *FieldTypeUpdateOne) SetValidateOptionalInt32(i int32) *FieldTypeUpdateOne { - ftuo.validate_optional_int32 = &i - ftuo.addvalidate_optional_int32 = nil + ftuo.mutation.ResetValidateOptionalInt32() + ftuo.mutation.SetValidateOptionalInt32(i) return ftuo } @@ -1536,25 +1249,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableValidateOptionalInt32(i *int32) *Fiel // AddValidateOptionalInt32 adds i to validate_optional_int32. func (ftuo *FieldTypeUpdateOne) AddValidateOptionalInt32(i int32) *FieldTypeUpdateOne { - if ftuo.addvalidate_optional_int32 == nil { - ftuo.addvalidate_optional_int32 = &i - } else { - *ftuo.addvalidate_optional_int32 += i - } + ftuo.mutation.AddValidateOptionalInt32(i) return ftuo } // ClearValidateOptionalInt32 clears the value of validate_optional_int32. func (ftuo *FieldTypeUpdateOne) ClearValidateOptionalInt32() *FieldTypeUpdateOne { - ftuo.validate_optional_int32 = nil - ftuo.clearvalidate_optional_int32 = true + ftuo.mutation.ClearValidateOptionalInt32() return ftuo } // SetOptionalUint sets the optional_uint field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint(u uint) *FieldTypeUpdateOne { - ftuo.optional_uint = &u - ftuo.addoptional_uint = nil + ftuo.mutation.ResetOptionalUint() + ftuo.mutation.SetOptionalUint(u) return ftuo } @@ -1568,25 +1276,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint(u *uint) *FieldTypeUpdat // AddOptionalUint adds u to optional_uint. func (ftuo *FieldTypeUpdateOne) AddOptionalUint(u uint) *FieldTypeUpdateOne { - if ftuo.addoptional_uint == nil { - ftuo.addoptional_uint = &u - } else { - *ftuo.addoptional_uint += u - } + ftuo.mutation.AddOptionalUint(u) return ftuo } // ClearOptionalUint clears the value of optional_uint. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint() *FieldTypeUpdateOne { - ftuo.optional_uint = nil - ftuo.clearoptional_uint = true + ftuo.mutation.ClearOptionalUint() return ftuo } // SetOptionalUint8 sets the optional_uint8 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint8(u uint8) *FieldTypeUpdateOne { - ftuo.optional_uint8 = &u - ftuo.addoptional_uint8 = nil + ftuo.mutation.ResetOptionalUint8() + ftuo.mutation.SetOptionalUint8(u) return ftuo } @@ -1600,25 +1303,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint8(u *uint8) *FieldTypeUpd // AddOptionalUint8 adds u to optional_uint8. func (ftuo *FieldTypeUpdateOne) AddOptionalUint8(u uint8) *FieldTypeUpdateOne { - if ftuo.addoptional_uint8 == nil { - ftuo.addoptional_uint8 = &u - } else { - *ftuo.addoptional_uint8 += u - } + ftuo.mutation.AddOptionalUint8(u) return ftuo } // ClearOptionalUint8 clears the value of optional_uint8. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint8() *FieldTypeUpdateOne { - ftuo.optional_uint8 = nil - ftuo.clearoptional_uint8 = true + ftuo.mutation.ClearOptionalUint8() return ftuo } // SetOptionalUint16 sets the optional_uint16 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint16(u uint16) *FieldTypeUpdateOne { - ftuo.optional_uint16 = &u - ftuo.addoptional_uint16 = nil + ftuo.mutation.ResetOptionalUint16() + ftuo.mutation.SetOptionalUint16(u) return ftuo } @@ -1632,25 +1330,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint16(u *uint16) *FieldTypeU // AddOptionalUint16 adds u to optional_uint16. func (ftuo *FieldTypeUpdateOne) AddOptionalUint16(u uint16) *FieldTypeUpdateOne { - if ftuo.addoptional_uint16 == nil { - ftuo.addoptional_uint16 = &u - } else { - *ftuo.addoptional_uint16 += u - } + ftuo.mutation.AddOptionalUint16(u) return ftuo } // ClearOptionalUint16 clears the value of optional_uint16. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint16() *FieldTypeUpdateOne { - ftuo.optional_uint16 = nil - ftuo.clearoptional_uint16 = true + ftuo.mutation.ClearOptionalUint16() return ftuo } // SetOptionalUint32 sets the optional_uint32 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint32(u uint32) *FieldTypeUpdateOne { - ftuo.optional_uint32 = &u - ftuo.addoptional_uint32 = nil + ftuo.mutation.ResetOptionalUint32() + ftuo.mutation.SetOptionalUint32(u) return ftuo } @@ -1664,25 +1357,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint32(u *uint32) *FieldTypeU // AddOptionalUint32 adds u to optional_uint32. func (ftuo *FieldTypeUpdateOne) AddOptionalUint32(u uint32) *FieldTypeUpdateOne { - if ftuo.addoptional_uint32 == nil { - ftuo.addoptional_uint32 = &u - } else { - *ftuo.addoptional_uint32 += u - } + ftuo.mutation.AddOptionalUint32(u) return ftuo } // ClearOptionalUint32 clears the value of optional_uint32. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint32() *FieldTypeUpdateOne { - ftuo.optional_uint32 = nil - ftuo.clearoptional_uint32 = true + ftuo.mutation.ClearOptionalUint32() return ftuo } // SetOptionalUint64 sets the optional_uint64 field. func (ftuo *FieldTypeUpdateOne) SetOptionalUint64(u uint64) *FieldTypeUpdateOne { - ftuo.optional_uint64 = &u - ftuo.addoptional_uint64 = nil + ftuo.mutation.ResetOptionalUint64() + ftuo.mutation.SetOptionalUint64(u) return ftuo } @@ -1696,24 +1384,19 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalUint64(u *uint64) *FieldTypeU // AddOptionalUint64 adds u to optional_uint64. func (ftuo *FieldTypeUpdateOne) AddOptionalUint64(u uint64) *FieldTypeUpdateOne { - if ftuo.addoptional_uint64 == nil { - ftuo.addoptional_uint64 = &u - } else { - *ftuo.addoptional_uint64 += u - } + ftuo.mutation.AddOptionalUint64(u) return ftuo } // ClearOptionalUint64 clears the value of optional_uint64. func (ftuo *FieldTypeUpdateOne) ClearOptionalUint64() *FieldTypeUpdateOne { - ftuo.optional_uint64 = nil - ftuo.clearoptional_uint64 = true + ftuo.mutation.ClearOptionalUint64() return ftuo } // SetState sets the state field. func (ftuo *FieldTypeUpdateOne) SetState(f fieldtype.State) *FieldTypeUpdateOne { - ftuo.state = &f + ftuo.mutation.SetState(f) return ftuo } @@ -1727,15 +1410,14 @@ func (ftuo *FieldTypeUpdateOne) SetNillableState(f *fieldtype.State) *FieldTypeU // ClearState clears the value of state. func (ftuo *FieldTypeUpdateOne) ClearState() *FieldTypeUpdateOne { - ftuo.state = nil - ftuo.clearstate = true + ftuo.mutation.ClearState() return ftuo } // SetOptionalFloat sets the optional_float field. func (ftuo *FieldTypeUpdateOne) SetOptionalFloat(f float64) *FieldTypeUpdateOne { - ftuo.optional_float = &f - ftuo.addoptional_float = nil + ftuo.mutation.ResetOptionalFloat() + ftuo.mutation.SetOptionalFloat(f) return ftuo } @@ -1749,25 +1431,20 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalFloat(f *float64) *FieldTypeU // AddOptionalFloat adds f to optional_float. func (ftuo *FieldTypeUpdateOne) AddOptionalFloat(f float64) *FieldTypeUpdateOne { - if ftuo.addoptional_float == nil { - ftuo.addoptional_float = &f - } else { - *ftuo.addoptional_float += f - } + ftuo.mutation.AddOptionalFloat(f) return ftuo } // ClearOptionalFloat clears the value of optional_float. func (ftuo *FieldTypeUpdateOne) ClearOptionalFloat() *FieldTypeUpdateOne { - ftuo.optional_float = nil - ftuo.clearoptional_float = true + ftuo.mutation.ClearOptionalFloat() return ftuo } // SetOptionalFloat32 sets the optional_float32 field. func (ftuo *FieldTypeUpdateOne) SetOptionalFloat32(f float32) *FieldTypeUpdateOne { - ftuo.optional_float32 = &f - ftuo.addoptional_float32 = nil + ftuo.mutation.ResetOptionalFloat32() + ftuo.mutation.SetOptionalFloat32(f) return ftuo } @@ -1781,34 +1458,52 @@ func (ftuo *FieldTypeUpdateOne) SetNillableOptionalFloat32(f *float32) *FieldTyp // AddOptionalFloat32 adds f to optional_float32. func (ftuo *FieldTypeUpdateOne) AddOptionalFloat32(f float32) *FieldTypeUpdateOne { - if ftuo.addoptional_float32 == nil { - ftuo.addoptional_float32 = &f - } else { - *ftuo.addoptional_float32 += f - } + ftuo.mutation.AddOptionalFloat32(f) return ftuo } // ClearOptionalFloat32 clears the value of optional_float32. func (ftuo *FieldTypeUpdateOne) ClearOptionalFloat32() *FieldTypeUpdateOne { - ftuo.optional_float32 = nil - ftuo.clearoptional_float32 = true + ftuo.mutation.ClearOptionalFloat32() return ftuo } // Save executes the query and returns the updated entity. func (ftuo *FieldTypeUpdateOne) Save(ctx context.Context) (*FieldType, error) { - if ftuo.validate_optional_int32 != nil { - if err := fieldtype.ValidateOptionalInt32Validator(*ftuo.validate_optional_int32); err != nil { + if v, ok := ftuo.mutation.ValidateOptionalInt32(); ok { + if err := fieldtype.ValidateOptionalInt32Validator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"validate_optional_int32\": %v", err) } } - if ftuo.state != nil { - if err := fieldtype.StateValidator(*ftuo.state); err != nil { + if v, ok := ftuo.mutation.State(); ok { + if err := fieldtype.StateValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"state\": %v", err) } } - return ftuo.gremlinSave(ctx) + var ( + err error + node *FieldType + ) + if len(ftuo.hooks) == 0 { + node, err = ftuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftuo.mutation = mutation + node, err = ftuo.gremlinSave(ctx) + return node, err + }) + for i := len(ftuo.hooks); i > 0; i-- { + mut = ftuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -1835,7 +1530,11 @@ func (ftuo *FieldTypeUpdateOne) ExecX(ctx context.Context) { func (ftuo *FieldTypeUpdateOne) gremlinSave(ctx context.Context) (*FieldType, error) { res := &gremlin.Response{} - query, bindings := ftuo.gremlin(ftuo.id).Query() + id, ok := ftuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing FieldType.ID for update") + } + query, bindings := ftuo.gremlin(id).Query() if err := ftuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -1854,203 +1553,203 @@ func (ftuo *FieldTypeUpdateOne) gremlin(id string) *dsl.Traversal { var ( trs []*dsl.Traversal ) - if value := ftuo.int; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt, *value) + if value, ok := ftuo.mutation.Int(); ok { + v.Property(dsl.Single, fieldtype.FieldInt, value) } - if value := ftuo.addint; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt, __.Union(__.Values(fieldtype.FieldInt), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedInt(); ok { + v.Property(dsl.Single, fieldtype.FieldInt, __.Union(__.Values(fieldtype.FieldInt), __.Constant(value)).Sum()) } - if value := ftuo.int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt8, *value) + if value, ok := ftuo.mutation.Int8(); ok { + v.Property(dsl.Single, fieldtype.FieldInt8, value) } - if value := ftuo.addint8; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt8, __.Union(__.Values(fieldtype.FieldInt8), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldInt8, __.Union(__.Values(fieldtype.FieldInt8), __.Constant(value)).Sum()) } - if value := ftuo.int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt16, *value) + if value, ok := ftuo.mutation.Int16(); ok { + v.Property(dsl.Single, fieldtype.FieldInt16, value) } - if value := ftuo.addint16; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt16, __.Union(__.Values(fieldtype.FieldInt16), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldInt16, __.Union(__.Values(fieldtype.FieldInt16), __.Constant(value)).Sum()) } - if value := ftuo.int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt32, *value) + if value, ok := ftuo.mutation.Int32(); ok { + v.Property(dsl.Single, fieldtype.FieldInt32, value) } - if value := ftuo.addint32; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt32, __.Union(__.Values(fieldtype.FieldInt32), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldInt32, __.Union(__.Values(fieldtype.FieldInt32), __.Constant(value)).Sum()) } - if value := ftuo.int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt64, *value) + if value, ok := ftuo.mutation.Int64(); ok { + v.Property(dsl.Single, fieldtype.FieldInt64, value) } - if value := ftuo.addint64; value != nil { - v.Property(dsl.Single, fieldtype.FieldInt64, __.Union(__.Values(fieldtype.FieldInt64), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldInt64, __.Union(__.Values(fieldtype.FieldInt64), __.Constant(value)).Sum()) } - if value := ftuo.optional_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt, *value) + if value, ok := ftuo.mutation.OptionalInt(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt, value) } - if value := ftuo.addoptional_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt, __.Union(__.Values(fieldtype.FieldOptionalInt), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalInt(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt, __.Union(__.Values(fieldtype.FieldOptionalInt), __.Constant(value)).Sum()) } - if value := ftuo.optional_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt8, *value) + if value, ok := ftuo.mutation.OptionalInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt8, value) } - if value := ftuo.addoptional_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt8, __.Union(__.Values(fieldtype.FieldOptionalInt8), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt8, __.Union(__.Values(fieldtype.FieldOptionalInt8), __.Constant(value)).Sum()) } - if value := ftuo.optional_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt16, *value) + if value, ok := ftuo.mutation.OptionalInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt16, value) } - if value := ftuo.addoptional_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt16, __.Union(__.Values(fieldtype.FieldOptionalInt16), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt16, __.Union(__.Values(fieldtype.FieldOptionalInt16), __.Constant(value)).Sum()) } - if value := ftuo.optional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt32, *value) + if value, ok := ftuo.mutation.OptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt32, value) } - if value := ftuo.addoptional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt32, __.Union(__.Values(fieldtype.FieldOptionalInt32), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt32, __.Union(__.Values(fieldtype.FieldOptionalInt32), __.Constant(value)).Sum()) } - if value := ftuo.optional_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt64, *value) + if value, ok := ftuo.mutation.OptionalInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt64, value) } - if value := ftuo.addoptional_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalInt64, __.Union(__.Values(fieldtype.FieldOptionalInt64), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalInt64, __.Union(__.Values(fieldtype.FieldOptionalInt64), __.Constant(value)).Sum()) } - if value := ftuo.nillable_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt, *value) + if value, ok := ftuo.mutation.NillableInt(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt, value) } - if value := ftuo.addnillable_int; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt, __.Union(__.Values(fieldtype.FieldNillableInt), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedNillableInt(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt, __.Union(__.Values(fieldtype.FieldNillableInt), __.Constant(value)).Sum()) } - if value := ftuo.nillable_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt8, *value) + if value, ok := ftuo.mutation.NillableInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt8, value) } - if value := ftuo.addnillable_int8; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt8, __.Union(__.Values(fieldtype.FieldNillableInt8), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedNillableInt8(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt8, __.Union(__.Values(fieldtype.FieldNillableInt8), __.Constant(value)).Sum()) } - if value := ftuo.nillable_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt16, *value) + if value, ok := ftuo.mutation.NillableInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt16, value) } - if value := ftuo.addnillable_int16; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt16, __.Union(__.Values(fieldtype.FieldNillableInt16), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedNillableInt16(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt16, __.Union(__.Values(fieldtype.FieldNillableInt16), __.Constant(value)).Sum()) } - if value := ftuo.nillable_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt32, *value) + if value, ok := ftuo.mutation.NillableInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt32, value) } - if value := ftuo.addnillable_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt32, __.Union(__.Values(fieldtype.FieldNillableInt32), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedNillableInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt32, __.Union(__.Values(fieldtype.FieldNillableInt32), __.Constant(value)).Sum()) } - if value := ftuo.nillable_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt64, *value) + if value, ok := ftuo.mutation.NillableInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt64, value) } - if value := ftuo.addnillable_int64; value != nil { - v.Property(dsl.Single, fieldtype.FieldNillableInt64, __.Union(__.Values(fieldtype.FieldNillableInt64), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedNillableInt64(); ok { + v.Property(dsl.Single, fieldtype.FieldNillableInt64, __.Union(__.Values(fieldtype.FieldNillableInt64), __.Constant(value)).Sum()) } - if value := ftuo.validate_optional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, *value) + if value, ok := ftuo.mutation.ValidateOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, value) } - if value := ftuo.addvalidate_optional_int32; value != nil { - v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, __.Union(__.Values(fieldtype.FieldValidateOptionalInt32), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedValidateOptionalInt32(); ok { + v.Property(dsl.Single, fieldtype.FieldValidateOptionalInt32, __.Union(__.Values(fieldtype.FieldValidateOptionalInt32), __.Constant(value)).Sum()) } - if value := ftuo.optional_uint; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint, *value) + if value, ok := ftuo.mutation.OptionalUint(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint, value) } - if value := ftuo.addoptional_uint; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint, __.Union(__.Values(fieldtype.FieldOptionalUint), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalUint(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint, __.Union(__.Values(fieldtype.FieldOptionalUint), __.Constant(value)).Sum()) } - if value := ftuo.optional_uint8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint8, *value) + if value, ok := ftuo.mutation.OptionalUint8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint8, value) } - if value := ftuo.addoptional_uint8; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint8, __.Union(__.Values(fieldtype.FieldOptionalUint8), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalUint8(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint8, __.Union(__.Values(fieldtype.FieldOptionalUint8), __.Constant(value)).Sum()) } - if value := ftuo.optional_uint16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint16, *value) + if value, ok := ftuo.mutation.OptionalUint16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint16, value) } - if value := ftuo.addoptional_uint16; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint16, __.Union(__.Values(fieldtype.FieldOptionalUint16), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalUint16(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint16, __.Union(__.Values(fieldtype.FieldOptionalUint16), __.Constant(value)).Sum()) } - if value := ftuo.optional_uint32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint32, *value) + if value, ok := ftuo.mutation.OptionalUint32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint32, value) } - if value := ftuo.addoptional_uint32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint32, __.Union(__.Values(fieldtype.FieldOptionalUint32), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalUint32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint32, __.Union(__.Values(fieldtype.FieldOptionalUint32), __.Constant(value)).Sum()) } - if value := ftuo.optional_uint64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint64, *value) + if value, ok := ftuo.mutation.OptionalUint64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint64, value) } - if value := ftuo.addoptional_uint64; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalUint64, __.Union(__.Values(fieldtype.FieldOptionalUint64), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalUint64(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalUint64, __.Union(__.Values(fieldtype.FieldOptionalUint64), __.Constant(value)).Sum()) } - if value := ftuo.state; value != nil { - v.Property(dsl.Single, fieldtype.FieldState, *value) + if value, ok := ftuo.mutation.State(); ok { + v.Property(dsl.Single, fieldtype.FieldState, value) } - if value := ftuo.optional_float; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat, *value) + if value, ok := ftuo.mutation.OptionalFloat(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat, value) } - if value := ftuo.addoptional_float; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat, __.Union(__.Values(fieldtype.FieldOptionalFloat), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalFloat(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat, __.Union(__.Values(fieldtype.FieldOptionalFloat), __.Constant(value)).Sum()) } - if value := ftuo.optional_float32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, *value) + if value, ok := ftuo.mutation.OptionalFloat32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, value) } - if value := ftuo.addoptional_float32; value != nil { - v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, __.Union(__.Values(fieldtype.FieldOptionalFloat32), __.Constant(*value)).Sum()) + if value, ok := ftuo.mutation.AddedOptionalFloat32(); ok { + v.Property(dsl.Single, fieldtype.FieldOptionalFloat32, __.Union(__.Values(fieldtype.FieldOptionalFloat32), __.Constant(value)).Sum()) } var properties []interface{} - if ftuo.clearoptional_int { + if ftuo.mutation.OptionalIntCleared() { properties = append(properties, fieldtype.FieldOptionalInt) } - if ftuo.clearoptional_int8 { + if ftuo.mutation.OptionalInt8Cleared() { properties = append(properties, fieldtype.FieldOptionalInt8) } - if ftuo.clearoptional_int16 { + if ftuo.mutation.OptionalInt16Cleared() { properties = append(properties, fieldtype.FieldOptionalInt16) } - if ftuo.clearoptional_int32 { + if ftuo.mutation.OptionalInt32Cleared() { properties = append(properties, fieldtype.FieldOptionalInt32) } - if ftuo.clearoptional_int64 { + if ftuo.mutation.OptionalInt64Cleared() { properties = append(properties, fieldtype.FieldOptionalInt64) } - if ftuo.clearnillable_int { + if ftuo.mutation.NillableIntCleared() { properties = append(properties, fieldtype.FieldNillableInt) } - if ftuo.clearnillable_int8 { + if ftuo.mutation.NillableInt8Cleared() { properties = append(properties, fieldtype.FieldNillableInt8) } - if ftuo.clearnillable_int16 { + if ftuo.mutation.NillableInt16Cleared() { properties = append(properties, fieldtype.FieldNillableInt16) } - if ftuo.clearnillable_int32 { + if ftuo.mutation.NillableInt32Cleared() { properties = append(properties, fieldtype.FieldNillableInt32) } - if ftuo.clearnillable_int64 { + if ftuo.mutation.NillableInt64Cleared() { properties = append(properties, fieldtype.FieldNillableInt64) } - if ftuo.clearvalidate_optional_int32 { + if ftuo.mutation.ValidateOptionalInt32Cleared() { properties = append(properties, fieldtype.FieldValidateOptionalInt32) } - if ftuo.clearoptional_uint { + if ftuo.mutation.OptionalUintCleared() { properties = append(properties, fieldtype.FieldOptionalUint) } - if ftuo.clearoptional_uint8 { + if ftuo.mutation.OptionalUint8Cleared() { properties = append(properties, fieldtype.FieldOptionalUint8) } - if ftuo.clearoptional_uint16 { + if ftuo.mutation.OptionalUint16Cleared() { properties = append(properties, fieldtype.FieldOptionalUint16) } - if ftuo.clearoptional_uint32 { + if ftuo.mutation.OptionalUint32Cleared() { properties = append(properties, fieldtype.FieldOptionalUint32) } - if ftuo.clearoptional_uint64 { + if ftuo.mutation.OptionalUint64Cleared() { properties = append(properties, fieldtype.FieldOptionalUint64) } - if ftuo.clearstate { + if ftuo.mutation.StateCleared() { properties = append(properties, fieldtype.FieldState) } - if ftuo.clearoptional_float { + if ftuo.mutation.OptionalFloatCleared() { properties = append(properties, fieldtype.FieldOptionalFloat) } - if ftuo.clearoptional_float32 { + if ftuo.mutation.OptionalFloat32Cleared() { properties = append(properties, fieldtype.FieldOptionalFloat32) } if len(properties) > 0 { diff --git a/entc/integration/gremlin/ent/file/file.go b/entc/integration/gremlin/ent/file/file.go index cdde97cc2..c214ff60a 100644 --- a/entc/integration/gremlin/ent/file/file.go +++ b/entc/integration/gremlin/ent/file/file.go @@ -6,24 +6,21 @@ package file -import ( - "github.com/facebookincubator/ent/entc/integration/ent/schema" -) - const ( // Label holds the string label denoting the file type in the database. Label = "file" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldSize holds the string denoting the size vertex property in the database. - FieldSize = "fsize" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" - // FieldUser holds the string denoting the user vertex property in the database. - FieldUser = "user" - // FieldGroup holds the string denoting the group vertex property in the database. + FieldID = "id" // FieldSize holds the string denoting the size vertex property in the database. + FieldSize = "fsize" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldUser holds the string denoting the user vertex property in the database. + FieldUser = "user" // FieldGroup holds the string denoting the group vertex property in the database. FieldGroup = "group" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // EdgeType holds the string denoting the type edge name in mutations. + EdgeType = "type" + // OwnerInverseLabel holds the string label denoting the owner inverse edge type in the database. OwnerInverseLabel = "user_files" // TypeInverseLabel holds the string label denoting the type inverse edge type in the database. @@ -31,12 +28,8 @@ const ( ) var ( - fields = schema.File{}.Fields() - - // descSize is the schema descriptor for size field. - descSize = fields[0].Descriptor() // DefaultSize holds the default value on creation for the size field. - DefaultSize = descSize.Default.(int) + DefaultSize int // SizeValidator is a validator for the "size" field. It is called by the builders before save. - SizeValidator = descSize.Validators[0].(func(int) error) + SizeValidator func(int) error ) diff --git a/entc/integration/gremlin/ent/file_create.go b/entc/integration/gremlin/ent/file_create.go index 196b41bef..8d8129238 100644 --- a/entc/integration/gremlin/ent/file_create.go +++ b/entc/integration/gremlin/ent/file_create.go @@ -22,17 +22,13 @@ import ( // FileCreate is the builder for creating a File entity. type FileCreate struct { config - size *int - name *string - user *string - group *string - owner map[string]struct{} - _type map[string]struct{} + mutation *FileMutation + hooks []Hook } // SetSize sets the size field. func (fc *FileCreate) SetSize(i int) *FileCreate { - fc.size = &i + fc.mutation.SetSize(i) return fc } @@ -46,13 +42,13 @@ func (fc *FileCreate) SetNillableSize(i *int) *FileCreate { // SetName sets the name field. func (fc *FileCreate) SetName(s string) *FileCreate { - fc.name = &s + fc.mutation.SetName(s) return fc } // SetUser sets the user field. func (fc *FileCreate) SetUser(s string) *FileCreate { - fc.user = &s + fc.mutation.SetUser(s) return fc } @@ -66,7 +62,7 @@ func (fc *FileCreate) SetNillableUser(s *string) *FileCreate { // SetGroup sets the group field. func (fc *FileCreate) SetGroup(s string) *FileCreate { - fc.group = &s + fc.mutation.SetGroup(s) return fc } @@ -80,10 +76,7 @@ func (fc *FileCreate) SetNillableGroup(s *string) *FileCreate { // SetOwnerID sets the owner edge to User by id. func (fc *FileCreate) SetOwnerID(id string) *FileCreate { - if fc.owner == nil { - fc.owner = make(map[string]struct{}) - } - fc.owner[id] = struct{}{} + fc.mutation.SetOwnerID(id) return fc } @@ -102,10 +95,7 @@ func (fc *FileCreate) SetOwner(u *User) *FileCreate { // SetTypeID sets the type edge to FileType by id. func (fc *FileCreate) SetTypeID(id string) *FileCreate { - if fc._type == nil { - fc._type = make(map[string]struct{}) - } - fc._type[id] = struct{}{} + fc.mutation.SetTypeID(id) return fc } @@ -124,23 +114,42 @@ func (fc *FileCreate) SetType(f *FileType) *FileCreate { // Save creates the File in the database. func (fc *FileCreate) Save(ctx context.Context) (*File, error) { - if fc.size == nil { + if _, ok := fc.mutation.Size(); !ok { v := file.DefaultSize - fc.size = &v + fc.mutation.SetSize(v) } - if err := file.SizeValidator(*fc.size); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"size\": %v", err) + if v, ok := fc.mutation.Size(); ok { + if err := file.SizeValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"size\": %v", err) + } } - if fc.name == nil { + if _, ok := fc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(fc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *File + ) + if len(fc.hooks) == 0 { + node, err = fc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fc.mutation = mutation + node, err = fc.gremlinSave(ctx) + return node, err + }) + for i := len(fc.hooks); i > 0; i-- { + mut = fc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fc.mutation); err != nil { + return nil, err + } } - if len(fc._type) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"type\"") - } - return fc.gremlinSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -170,22 +179,22 @@ func (fc *FileCreate) gremlinSave(ctx context.Context) (*File, error) { func (fc *FileCreate) gremlin() *dsl.Traversal { v := g.AddV(file.Label) - if fc.size != nil { - v.Property(dsl.Single, file.FieldSize, *fc.size) + if value, ok := fc.mutation.Size(); ok { + v.Property(dsl.Single, file.FieldSize, value) } - if fc.name != nil { - v.Property(dsl.Single, file.FieldName, *fc.name) + if value, ok := fc.mutation.Name(); ok { + v.Property(dsl.Single, file.FieldName, value) } - if fc.user != nil { - v.Property(dsl.Single, file.FieldUser, *fc.user) + if value, ok := fc.mutation.User(); ok { + v.Property(dsl.Single, file.FieldUser, value) } - if fc.group != nil { - v.Property(dsl.Single, file.FieldGroup, *fc.group) + if value, ok := fc.mutation.Group(); ok { + v.Property(dsl.Single, file.FieldGroup, value) } - for id := range fc.owner { + for _, id := range fc.mutation.OwnerIDs() { v.AddE(user.FilesLabel).From(g.V(id)).InV() } - for id := range fc._type { + for _, id := range fc.mutation.TypeIDs() { v.AddE(filetype.FilesLabel).From(g.V(id)).InV() } return v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/file_delete.go b/entc/integration/gremlin/ent/file_delete.go index 291519bbe..0c2db22d3 100644 --- a/entc/integration/gremlin/ent/file_delete.go +++ b/entc/integration/gremlin/ent/file_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // FileDelete is the builder for deleting a File entity. type FileDelete struct { config + hooks []Hook + mutation *FileMutation predicates []predicate.File } @@ -31,7 +34,30 @@ func (fd *FileDelete) Where(ps ...predicate.File) *FileDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (fd *FileDelete) Exec(ctx context.Context) (int, error) { - return fd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(fd.hooks) == 0 { + affected, err = fd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fd.mutation = mutation + affected, err = fd.gremlinExec(ctx) + return affected, err + }) + for i := len(fd.hooks); i > 0; i-- { + mut = fd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/file_update.go b/entc/integration/gremlin/ent/file_update.go index ee4887817..e2cbe2a01 100644 --- a/entc/integration/gremlin/ent/file_update.go +++ b/entc/integration/gremlin/ent/file_update.go @@ -8,7 +8,6 @@ package ent import ( "context" - "errors" "fmt" "github.com/facebookincubator/ent/dialect/gremlin" @@ -24,18 +23,9 @@ import ( // FileUpdate is the builder for updating File entities. type FileUpdate struct { config - size *int - addsize *int - name *string - user *string - clearuser bool - group *string - cleargroup bool - owner map[string]struct{} - _type map[string]struct{} - clearedOwner bool - clearedType bool - predicates []predicate.File + hooks []Hook + mutation *FileMutation + predicates []predicate.File } // Where adds a new predicate for the builder. @@ -46,8 +36,8 @@ func (fu *FileUpdate) Where(ps ...predicate.File) *FileUpdate { // SetSize sets the size field. func (fu *FileUpdate) SetSize(i int) *FileUpdate { - fu.size = &i - fu.addsize = nil + fu.mutation.ResetSize() + fu.mutation.SetSize(i) return fu } @@ -61,23 +51,19 @@ func (fu *FileUpdate) SetNillableSize(i *int) *FileUpdate { // AddSize adds i to size. func (fu *FileUpdate) AddSize(i int) *FileUpdate { - if fu.addsize == nil { - fu.addsize = &i - } else { - *fu.addsize += i - } + fu.mutation.AddSize(i) return fu } // SetName sets the name field. func (fu *FileUpdate) SetName(s string) *FileUpdate { - fu.name = &s + fu.mutation.SetName(s) return fu } // SetUser sets the user field. func (fu *FileUpdate) SetUser(s string) *FileUpdate { - fu.user = &s + fu.mutation.SetUser(s) return fu } @@ -91,14 +77,13 @@ func (fu *FileUpdate) SetNillableUser(s *string) *FileUpdate { // ClearUser clears the value of user. func (fu *FileUpdate) ClearUser() *FileUpdate { - fu.user = nil - fu.clearuser = true + fu.mutation.ClearUser() return fu } // SetGroup sets the group field. func (fu *FileUpdate) SetGroup(s string) *FileUpdate { - fu.group = &s + fu.mutation.SetGroup(s) return fu } @@ -112,17 +97,13 @@ func (fu *FileUpdate) SetNillableGroup(s *string) *FileUpdate { // ClearGroup clears the value of group. func (fu *FileUpdate) ClearGroup() *FileUpdate { - fu.group = nil - fu.cleargroup = true + fu.mutation.ClearGroup() return fu } // SetOwnerID sets the owner edge to User by id. func (fu *FileUpdate) SetOwnerID(id string) *FileUpdate { - if fu.owner == nil { - fu.owner = make(map[string]struct{}) - } - fu.owner[id] = struct{}{} + fu.mutation.SetOwnerID(id) return fu } @@ -141,10 +122,7 @@ func (fu *FileUpdate) SetOwner(u *User) *FileUpdate { // SetTypeID sets the type edge to FileType by id. func (fu *FileUpdate) SetTypeID(id string) *FileUpdate { - if fu._type == nil { - fu._type = make(map[string]struct{}) - } - fu._type[id] = struct{}{} + fu.mutation.SetTypeID(id) return fu } @@ -163,30 +141,48 @@ func (fu *FileUpdate) SetType(f *FileType) *FileUpdate { // ClearOwner clears the owner edge to User. func (fu *FileUpdate) ClearOwner() *FileUpdate { - fu.clearedOwner = true + fu.mutation.ClearOwner() return fu } // ClearType clears the type edge to FileType. func (fu *FileUpdate) ClearType() *FileUpdate { - fu.clearedType = true + fu.mutation.ClearType() return fu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (fu *FileUpdate) Save(ctx context.Context) (int, error) { - if fu.size != nil { - if err := file.SizeValidator(*fu.size); err != nil { + if v, ok := fu.mutation.Size(); ok { + if err := file.SizeValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"size\": %v", err) } } - if len(fu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(fu.hooks) == 0 { + affected, err = fu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fu.mutation = mutation + affected, err = fu.gremlinSave(ctx) + return affected, err + }) + for i := len(fu.hooks); i > 0; i-- { + mut = fu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fu.mutation); err != nil { + return 0, err + } } - if len(fu._type) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"type\"") - } - return fu.gremlinSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -234,43 +230,43 @@ func (fu *FileUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := fu.size; value != nil { - v.Property(dsl.Single, file.FieldSize, *value) + if value, ok := fu.mutation.Size(); ok { + v.Property(dsl.Single, file.FieldSize, value) } - if value := fu.addsize; value != nil { - v.Property(dsl.Single, file.FieldSize, __.Union(__.Values(file.FieldSize), __.Constant(*value)).Sum()) + if value, ok := fu.mutation.AddedSize(); ok { + v.Property(dsl.Single, file.FieldSize, __.Union(__.Values(file.FieldSize), __.Constant(value)).Sum()) } - if value := fu.name; value != nil { - v.Property(dsl.Single, file.FieldName, *value) + if value, ok := fu.mutation.Name(); ok { + v.Property(dsl.Single, file.FieldName, value) } - if value := fu.user; value != nil { - v.Property(dsl.Single, file.FieldUser, *value) + if value, ok := fu.mutation.User(); ok { + v.Property(dsl.Single, file.FieldUser, value) } - if value := fu.group; value != nil { - v.Property(dsl.Single, file.FieldGroup, *value) + if value, ok := fu.mutation.Group(); ok { + v.Property(dsl.Single, file.FieldGroup, value) } var properties []interface{} - if fu.clearuser { + if fu.mutation.UserCleared() { properties = append(properties, file.FieldUser) } - if fu.cleargroup { + if fu.mutation.GroupCleared() { properties = append(properties, file.FieldGroup) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if fu.clearedOwner { + if fu.mutation.OwnerCleared() { tr := rv.Clone().InE(user.FilesLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range fu.owner { + for _, id := range fu.mutation.OwnerIDs() { v.AddE(user.FilesLabel).From(g.V(id)).InV() } - if fu.clearedType { + if fu.mutation.TypeCleared() { tr := rv.Clone().InE(filetype.FilesLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range fu._type { + for _, id := range fu.mutation.TypeIDs() { v.AddE(filetype.FilesLabel).From(g.V(id)).InV() } v.Count() @@ -281,24 +277,14 @@ func (fu *FileUpdate) gremlin() *dsl.Traversal { // FileUpdateOne is the builder for updating a single File entity. type FileUpdateOne struct { config - id string - size *int - addsize *int - name *string - user *string - clearuser bool - group *string - cleargroup bool - owner map[string]struct{} - _type map[string]struct{} - clearedOwner bool - clearedType bool + hooks []Hook + mutation *FileMutation } // SetSize sets the size field. func (fuo *FileUpdateOne) SetSize(i int) *FileUpdateOne { - fuo.size = &i - fuo.addsize = nil + fuo.mutation.ResetSize() + fuo.mutation.SetSize(i) return fuo } @@ -312,23 +298,19 @@ func (fuo *FileUpdateOne) SetNillableSize(i *int) *FileUpdateOne { // AddSize adds i to size. func (fuo *FileUpdateOne) AddSize(i int) *FileUpdateOne { - if fuo.addsize == nil { - fuo.addsize = &i - } else { - *fuo.addsize += i - } + fuo.mutation.AddSize(i) return fuo } // SetName sets the name field. func (fuo *FileUpdateOne) SetName(s string) *FileUpdateOne { - fuo.name = &s + fuo.mutation.SetName(s) return fuo } // SetUser sets the user field. func (fuo *FileUpdateOne) SetUser(s string) *FileUpdateOne { - fuo.user = &s + fuo.mutation.SetUser(s) return fuo } @@ -342,14 +324,13 @@ func (fuo *FileUpdateOne) SetNillableUser(s *string) *FileUpdateOne { // ClearUser clears the value of user. func (fuo *FileUpdateOne) ClearUser() *FileUpdateOne { - fuo.user = nil - fuo.clearuser = true + fuo.mutation.ClearUser() return fuo } // SetGroup sets the group field. func (fuo *FileUpdateOne) SetGroup(s string) *FileUpdateOne { - fuo.group = &s + fuo.mutation.SetGroup(s) return fuo } @@ -363,17 +344,13 @@ func (fuo *FileUpdateOne) SetNillableGroup(s *string) *FileUpdateOne { // ClearGroup clears the value of group. func (fuo *FileUpdateOne) ClearGroup() *FileUpdateOne { - fuo.group = nil - fuo.cleargroup = true + fuo.mutation.ClearGroup() return fuo } // SetOwnerID sets the owner edge to User by id. func (fuo *FileUpdateOne) SetOwnerID(id string) *FileUpdateOne { - if fuo.owner == nil { - fuo.owner = make(map[string]struct{}) - } - fuo.owner[id] = struct{}{} + fuo.mutation.SetOwnerID(id) return fuo } @@ -392,10 +369,7 @@ func (fuo *FileUpdateOne) SetOwner(u *User) *FileUpdateOne { // SetTypeID sets the type edge to FileType by id. func (fuo *FileUpdateOne) SetTypeID(id string) *FileUpdateOne { - if fuo._type == nil { - fuo._type = make(map[string]struct{}) - } - fuo._type[id] = struct{}{} + fuo.mutation.SetTypeID(id) return fuo } @@ -414,30 +388,48 @@ func (fuo *FileUpdateOne) SetType(f *FileType) *FileUpdateOne { // ClearOwner clears the owner edge to User. func (fuo *FileUpdateOne) ClearOwner() *FileUpdateOne { - fuo.clearedOwner = true + fuo.mutation.ClearOwner() return fuo } // ClearType clears the type edge to FileType. func (fuo *FileUpdateOne) ClearType() *FileUpdateOne { - fuo.clearedType = true + fuo.mutation.ClearType() return fuo } // Save executes the query and returns the updated entity. func (fuo *FileUpdateOne) Save(ctx context.Context) (*File, error) { - if fuo.size != nil { - if err := file.SizeValidator(*fuo.size); err != nil { + if v, ok := fuo.mutation.Size(); ok { + if err := file.SizeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"size\": %v", err) } } - if len(fuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *File + ) + if len(fuo.hooks) == 0 { + node, err = fuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + fuo.mutation = mutation + node, err = fuo.gremlinSave(ctx) + return node, err + }) + for i := len(fuo.hooks); i > 0; i-- { + mut = fuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, fuo.mutation); err != nil { + return nil, err + } } - if len(fuo._type) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"type\"") - } - return fuo.gremlinSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -464,7 +456,11 @@ func (fuo *FileUpdateOne) ExecX(ctx context.Context) { func (fuo *FileUpdateOne) gremlinSave(ctx context.Context) (*File, error) { res := &gremlin.Response{} - query, bindings := fuo.gremlin(fuo.id).Query() + id, ok := fuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing File.ID for update") + } + query, bindings := fuo.gremlin(id).Query() if err := fuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -486,43 +482,43 @@ func (fuo *FileUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := fuo.size; value != nil { - v.Property(dsl.Single, file.FieldSize, *value) + if value, ok := fuo.mutation.Size(); ok { + v.Property(dsl.Single, file.FieldSize, value) } - if value := fuo.addsize; value != nil { - v.Property(dsl.Single, file.FieldSize, __.Union(__.Values(file.FieldSize), __.Constant(*value)).Sum()) + if value, ok := fuo.mutation.AddedSize(); ok { + v.Property(dsl.Single, file.FieldSize, __.Union(__.Values(file.FieldSize), __.Constant(value)).Sum()) } - if value := fuo.name; value != nil { - v.Property(dsl.Single, file.FieldName, *value) + if value, ok := fuo.mutation.Name(); ok { + v.Property(dsl.Single, file.FieldName, value) } - if value := fuo.user; value != nil { - v.Property(dsl.Single, file.FieldUser, *value) + if value, ok := fuo.mutation.User(); ok { + v.Property(dsl.Single, file.FieldUser, value) } - if value := fuo.group; value != nil { - v.Property(dsl.Single, file.FieldGroup, *value) + if value, ok := fuo.mutation.Group(); ok { + v.Property(dsl.Single, file.FieldGroup, value) } var properties []interface{} - if fuo.clearuser { + if fuo.mutation.UserCleared() { properties = append(properties, file.FieldUser) } - if fuo.cleargroup { + if fuo.mutation.GroupCleared() { properties = append(properties, file.FieldGroup) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if fuo.clearedOwner { + if fuo.mutation.OwnerCleared() { tr := rv.Clone().InE(user.FilesLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range fuo.owner { + for _, id := range fuo.mutation.OwnerIDs() { v.AddE(user.FilesLabel).From(g.V(id)).InV() } - if fuo.clearedType { + if fuo.mutation.TypeCleared() { tr := rv.Clone().InE(filetype.FilesLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range fuo._type { + for _, id := range fuo.mutation.TypeIDs() { v.AddE(filetype.FilesLabel).From(g.V(id)).InV() } v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/filetype/filetype.go b/entc/integration/gremlin/ent/filetype/filetype.go index b5f443223..540f867d0 100644 --- a/entc/integration/gremlin/ent/filetype/filetype.go +++ b/entc/integration/gremlin/ent/filetype/filetype.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the filetype type in the database. Label = "file_type" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeFiles holds the string denoting the files edge name in mutations. + EdgeFiles = "files" + // FilesLabel holds the string label denoting the files edge type in the database. FilesLabel = "file_type_files" ) diff --git a/entc/integration/gremlin/ent/filetype_create.go b/entc/integration/gremlin/ent/filetype_create.go index 710012f57..d204e9825 100644 --- a/entc/integration/gremlin/ent/filetype_create.go +++ b/entc/integration/gremlin/ent/filetype_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -21,24 +22,19 @@ import ( // FileTypeCreate is the builder for creating a FileType entity. type FileTypeCreate struct { config - name *string - files map[string]struct{} + mutation *FileTypeMutation + hooks []Hook } // SetName sets the name field. func (ftc *FileTypeCreate) SetName(s string) *FileTypeCreate { - ftc.name = &s + ftc.mutation.SetName(s) return ftc } // AddFileIDs adds the files edge to File by ids. func (ftc *FileTypeCreate) AddFileIDs(ids ...string) *FileTypeCreate { - if ftc.files == nil { - ftc.files = make(map[string]struct{}) - } - for i := range ids { - ftc.files[ids[i]] = struct{}{} - } + ftc.mutation.AddFileIDs(ids...) return ftc } @@ -53,10 +49,33 @@ func (ftc *FileTypeCreate) AddFiles(f ...*File) *FileTypeCreate { // Save creates the FileType in the database. func (ftc *FileTypeCreate) Save(ctx context.Context) (*FileType, error) { - if ftc.name == nil { + if _, ok := ftc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return ftc.gremlinSave(ctx) + var ( + err error + node *FileType + ) + if len(ftc.hooks) == 0 { + node, err = ftc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftc.mutation = mutation + node, err = ftc.gremlinSave(ctx) + return node, err + }) + for i := len(ftc.hooks); i > 0; i-- { + mut = ftc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -91,14 +110,14 @@ func (ftc *FileTypeCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 2) v := g.AddV(filetype.Label) - if ftc.name != nil { + if value, ok := ftc.mutation.Name(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(filetype.Label, filetype.FieldName, *ftc.name).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(filetype.Label, filetype.FieldName, *ftc.name)), + pred: g.V().Has(filetype.Label, filetype.FieldName, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(filetype.Label, filetype.FieldName, value)), }) - v.Property(dsl.Single, filetype.FieldName, *ftc.name) + v.Property(dsl.Single, filetype.FieldName, value) } - for id := range ftc.files { + for _, id := range ftc.mutation.FilesIDs() { v.AddE(filetype.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(filetype.FilesLabel).InV().HasID(id).Count(), diff --git a/entc/integration/gremlin/ent/filetype_delete.go b/entc/integration/gremlin/ent/filetype_delete.go index b6a68e1b6..ea23b87f0 100644 --- a/entc/integration/gremlin/ent/filetype_delete.go +++ b/entc/integration/gremlin/ent/filetype_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // FileTypeDelete is the builder for deleting a FileType entity. type FileTypeDelete struct { config + hooks []Hook + mutation *FileTypeMutation predicates []predicate.FileType } @@ -31,7 +34,30 @@ func (ftd *FileTypeDelete) Where(ps ...predicate.FileType) *FileTypeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ftd *FileTypeDelete) Exec(ctx context.Context) (int, error) { - return ftd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(ftd.hooks) == 0 { + affected, err = ftd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftd.mutation = mutation + affected, err = ftd.gremlinExec(ctx) + return affected, err + }) + for i := len(ftd.hooks); i > 0; i-- { + mut = ftd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/filetype_update.go b/entc/integration/gremlin/ent/filetype_update.go index fdb990c8c..8ebe44118 100644 --- a/entc/integration/gremlin/ent/filetype_update.go +++ b/entc/integration/gremlin/ent/filetype_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -21,10 +22,9 @@ import ( // FileTypeUpdate is the builder for updating FileType entities. type FileTypeUpdate struct { config - name *string - files map[string]struct{} - removedFiles map[string]struct{} - predicates []predicate.FileType + hooks []Hook + mutation *FileTypeMutation + predicates []predicate.FileType } // Where adds a new predicate for the builder. @@ -35,18 +35,13 @@ func (ftu *FileTypeUpdate) Where(ps ...predicate.FileType) *FileTypeUpdate { // SetName sets the name field. func (ftu *FileTypeUpdate) SetName(s string) *FileTypeUpdate { - ftu.name = &s + ftu.mutation.SetName(s) return ftu } // AddFileIDs adds the files edge to File by ids. func (ftu *FileTypeUpdate) AddFileIDs(ids ...string) *FileTypeUpdate { - if ftu.files == nil { - ftu.files = make(map[string]struct{}) - } - for i := range ids { - ftu.files[ids[i]] = struct{}{} - } + ftu.mutation.AddFileIDs(ids...) return ftu } @@ -61,12 +56,7 @@ func (ftu *FileTypeUpdate) AddFiles(f ...*File) *FileTypeUpdate { // RemoveFileIDs removes the files edge to File by ids. func (ftu *FileTypeUpdate) RemoveFileIDs(ids ...string) *FileTypeUpdate { - if ftu.removedFiles == nil { - ftu.removedFiles = make(map[string]struct{}) - } - for i := range ids { - ftu.removedFiles[ids[i]] = struct{}{} - } + ftu.mutation.RemoveFileIDs(ids...) return ftu } @@ -81,7 +71,31 @@ func (ftu *FileTypeUpdate) RemoveFiles(f ...*File) *FileTypeUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (ftu *FileTypeUpdate) Save(ctx context.Context) (int, error) { - return ftu.gremlinSave(ctx) + + var ( + err error + affected int + ) + if len(ftu.hooks) == 0 { + affected, err = ftu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftu.mutation = mutation + affected, err = ftu.gremlinSave(ctx) + return affected, err + }) + for i := len(ftu.hooks); i > 0; i-- { + mut = ftu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -134,18 +148,18 @@ func (ftu *FileTypeUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := ftu.name; value != nil { + if value, ok := ftu.mutation.Name(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(filetype.Label, filetype.FieldName, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(filetype.Label, filetype.FieldName, *value)), + pred: g.V().Has(filetype.Label, filetype.FieldName, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(filetype.Label, filetype.FieldName, value)), }) - v.Property(dsl.Single, filetype.FieldName, *value) + v.Property(dsl.Single, filetype.FieldName, value) } - for id := range ftu.removedFiles { + for _, id := range ftu.mutation.RemovedFilesIDs() { tr := rv.Clone().OutE(filetype.FilesLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range ftu.files { + for _, id := range ftu.mutation.FilesIDs() { v.AddE(filetype.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(filetype.FilesLabel).InV().HasID(id).Count(), @@ -170,26 +184,19 @@ func (ftu *FileTypeUpdate) gremlin() *dsl.Traversal { // FileTypeUpdateOne is the builder for updating a single FileType entity. type FileTypeUpdateOne struct { config - id string - name *string - files map[string]struct{} - removedFiles map[string]struct{} + hooks []Hook + mutation *FileTypeMutation } // SetName sets the name field. func (ftuo *FileTypeUpdateOne) SetName(s string) *FileTypeUpdateOne { - ftuo.name = &s + ftuo.mutation.SetName(s) return ftuo } // AddFileIDs adds the files edge to File by ids. func (ftuo *FileTypeUpdateOne) AddFileIDs(ids ...string) *FileTypeUpdateOne { - if ftuo.files == nil { - ftuo.files = make(map[string]struct{}) - } - for i := range ids { - ftuo.files[ids[i]] = struct{}{} - } + ftuo.mutation.AddFileIDs(ids...) return ftuo } @@ -204,12 +211,7 @@ func (ftuo *FileTypeUpdateOne) AddFiles(f ...*File) *FileTypeUpdateOne { // RemoveFileIDs removes the files edge to File by ids. func (ftuo *FileTypeUpdateOne) RemoveFileIDs(ids ...string) *FileTypeUpdateOne { - if ftuo.removedFiles == nil { - ftuo.removedFiles = make(map[string]struct{}) - } - for i := range ids { - ftuo.removedFiles[ids[i]] = struct{}{} - } + ftuo.mutation.RemoveFileIDs(ids...) return ftuo } @@ -224,7 +226,31 @@ func (ftuo *FileTypeUpdateOne) RemoveFiles(f ...*File) *FileTypeUpdateOne { // Save executes the query and returns the updated entity. func (ftuo *FileTypeUpdateOne) Save(ctx context.Context) (*FileType, error) { - return ftuo.gremlinSave(ctx) + + var ( + err error + node *FileType + ) + if len(ftuo.hooks) == 0 { + node, err = ftuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ftuo.mutation = mutation + node, err = ftuo.gremlinSave(ctx) + return node, err + }) + for i := len(ftuo.hooks); i > 0; i-- { + mut = ftuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ftuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -251,7 +277,11 @@ func (ftuo *FileTypeUpdateOne) ExecX(ctx context.Context) { func (ftuo *FileTypeUpdateOne) gremlinSave(ctx context.Context) (*FileType, error) { res := &gremlin.Response{} - query, bindings := ftuo.gremlin(ftuo.id).Query() + id, ok := ftuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing FileType.ID for update") + } + query, bindings := ftuo.gremlin(id).Query() if err := ftuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -278,18 +308,18 @@ func (ftuo *FileTypeUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := ftuo.name; value != nil { + if value, ok := ftuo.mutation.Name(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(filetype.Label, filetype.FieldName, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(filetype.Label, filetype.FieldName, *value)), + pred: g.V().Has(filetype.Label, filetype.FieldName, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(filetype.Label, filetype.FieldName, value)), }) - v.Property(dsl.Single, filetype.FieldName, *value) + v.Property(dsl.Single, filetype.FieldName, value) } - for id := range ftuo.removedFiles { + for _, id := range ftuo.mutation.RemovedFilesIDs() { tr := rv.Clone().OutE(filetype.FilesLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range ftuo.files { + for _, id := range ftuo.mutation.FilesIDs() { v.AddE(filetype.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(filetype.FilesLabel).InV().HasID(id).Count(), diff --git a/entc/integration/gremlin/ent/group/group.go b/entc/integration/gremlin/ent/group/group.go index 496e619d5..fd14276af 100644 --- a/entc/integration/gremlin/ent/group/group.go +++ b/entc/integration/gremlin/ent/group/group.go @@ -6,25 +6,25 @@ package group -import ( - "github.com/facebookincubator/ent/entc/integration/ent/schema" -) - const ( // Label holds the string label denoting the group type in the database. Label = "group" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldActive holds the string denoting the active vertex property in the database. - FieldActive = "active" - // FieldExpire holds the string denoting the expire vertex property in the database. - FieldExpire = "expire" - // FieldType holds the string denoting the type vertex property in the database. - FieldType = "type" - // FieldMaxUsers holds the string denoting the max_users vertex property in the database. - FieldMaxUsers = "max_users" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" + FieldID = "id" // FieldActive holds the string denoting the active vertex property in the database. + FieldActive = "active" // FieldExpire holds the string denoting the expire vertex property in the database. + FieldExpire = "expire" // FieldType holds the string denoting the type vertex property in the database. + FieldType = "type" // FieldMaxUsers holds the string denoting the max_users vertex property in the database. + FieldMaxUsers = "max_users" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" + + // EdgeFiles holds the string denoting the files edge name in mutations. + EdgeFiles = "files" + // EdgeBlocked holds the string denoting the blocked edge name in mutations. + EdgeBlocked = "blocked" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // EdgeInfo holds the string denoting the info edge name in mutations. + EdgeInfo = "info" // FilesLabel holds the string label denoting the files edge type in the database. FilesLabel = "group_files" @@ -37,55 +37,14 @@ const ( ) var ( - fields = schema.Group{}.Fields() - - // descActive is the schema descriptor for active field. - descActive = fields[0].Descriptor() // DefaultActive holds the default value on creation for the active field. - DefaultActive = descActive.Default.(bool) - - // descType is the schema descriptor for type field. - descType = fields[2].Descriptor() + DefaultActive bool // TypeValidator is a validator for the "type" field. It is called by the builders before save. - TypeValidator = func() func(string) error { - validators := descType.Validators - fns := [...]func(string) error{ - validators[0].(func(string) error), - validators[1].(func(string) error), - } - return func(_type string) error { - for _, fn := range fns { - if err := fn(_type); err != nil { - return err - } - } - return nil - } - }() - - // descMaxUsers is the schema descriptor for max_users field. - descMaxUsers = fields[3].Descriptor() + TypeValidator func(string) error // DefaultMaxUsers holds the default value on creation for the max_users field. - DefaultMaxUsers = descMaxUsers.Default.(int) + DefaultMaxUsers int // MaxUsersValidator is a validator for the "max_users" field. It is called by the builders before save. - MaxUsersValidator = descMaxUsers.Validators[0].(func(int) error) - - // descName is the schema descriptor for name field. - descName = fields[4].Descriptor() + MaxUsersValidator func(int) error // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator = func() func(string) error { - validators := descName.Validators - fns := [...]func(string) error{ - validators[0].(func(string) error), - validators[1].(func(string) error), - } - return func(name string) error { - for _, fn := range fns { - if err := fn(name); err != nil { - return err - } - } - return nil - } - }() + NameValidator func(string) error ) diff --git a/entc/integration/gremlin/ent/group_create.go b/entc/integration/gremlin/ent/group_create.go index 69cee6076..bc60d31df 100644 --- a/entc/integration/gremlin/ent/group_create.go +++ b/entc/integration/gremlin/ent/group_create.go @@ -24,20 +24,13 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - active *bool - expire *time.Time - _type *string - max_users *int - name *string - files map[string]struct{} - blocked map[string]struct{} - users map[string]struct{} - info map[string]struct{} + mutation *GroupMutation + hooks []Hook } // SetActive sets the active field. func (gc *GroupCreate) SetActive(b bool) *GroupCreate { - gc.active = &b + gc.mutation.SetActive(b) return gc } @@ -51,13 +44,13 @@ func (gc *GroupCreate) SetNillableActive(b *bool) *GroupCreate { // SetExpire sets the expire field. func (gc *GroupCreate) SetExpire(t time.Time) *GroupCreate { - gc.expire = &t + gc.mutation.SetExpire(t) return gc } // SetType sets the type field. func (gc *GroupCreate) SetType(s string) *GroupCreate { - gc._type = &s + gc.mutation.SetType(s) return gc } @@ -71,7 +64,7 @@ func (gc *GroupCreate) SetNillableType(s *string) *GroupCreate { // SetMaxUsers sets the max_users field. func (gc *GroupCreate) SetMaxUsers(i int) *GroupCreate { - gc.max_users = &i + gc.mutation.SetMaxUsers(i) return gc } @@ -85,18 +78,13 @@ func (gc *GroupCreate) SetNillableMaxUsers(i *int) *GroupCreate { // SetName sets the name field. func (gc *GroupCreate) SetName(s string) *GroupCreate { - gc.name = &s + gc.mutation.SetName(s) return gc } // AddFileIDs adds the files edge to File by ids. func (gc *GroupCreate) AddFileIDs(ids ...string) *GroupCreate { - if gc.files == nil { - gc.files = make(map[string]struct{}) - } - for i := range ids { - gc.files[ids[i]] = struct{}{} - } + gc.mutation.AddFileIDs(ids...) return gc } @@ -111,12 +99,7 @@ func (gc *GroupCreate) AddFiles(f ...*File) *GroupCreate { // AddBlockedIDs adds the blocked edge to User by ids. func (gc *GroupCreate) AddBlockedIDs(ids ...string) *GroupCreate { - if gc.blocked == nil { - gc.blocked = make(map[string]struct{}) - } - for i := range ids { - gc.blocked[ids[i]] = struct{}{} - } + gc.mutation.AddBlockedIDs(ids...) return gc } @@ -131,12 +114,7 @@ func (gc *GroupCreate) AddBlocked(u ...*User) *GroupCreate { // AddUserIDs adds the users edge to User by ids. func (gc *GroupCreate) AddUserIDs(ids ...string) *GroupCreate { - if gc.users == nil { - gc.users = make(map[string]struct{}) - } - for i := range ids { - gc.users[ids[i]] = struct{}{} - } + gc.mutation.AddUserIDs(ids...) return gc } @@ -151,10 +129,7 @@ func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { // SetInfoID sets the info edge to GroupInfo by id. func (gc *GroupCreate) SetInfoID(id string) *GroupCreate { - if gc.info == nil { - gc.info = make(map[string]struct{}) - } - gc.info[id] = struct{}{} + gc.mutation.SetInfoID(id) return gc } @@ -165,38 +140,62 @@ func (gc *GroupCreate) SetInfo(g *GroupInfo) *GroupCreate { // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - if gc.active == nil { + if _, ok := gc.mutation.Active(); !ok { v := group.DefaultActive - gc.active = &v + gc.mutation.SetActive(v) } - if gc.expire == nil { + if _, ok := gc.mutation.Expire(); !ok { return nil, errors.New("ent: missing required field \"expire\"") } - if gc._type != nil { - if err := group.TypeValidator(*gc._type); err != nil { + if v, ok := gc.mutation.GetType(); ok { + if err := group.TypeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"type\": %v", err) } } - if gc.max_users == nil { + if _, ok := gc.mutation.MaxUsers(); !ok { v := group.DefaultMaxUsers - gc.max_users = &v + gc.mutation.SetMaxUsers(v) } - if err := group.MaxUsersValidator(*gc.max_users); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) + if v, ok := gc.mutation.MaxUsers(); ok { + if err := group.MaxUsersValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) + } } - if gc.name == nil { + if _, ok := gc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if err := group.NameValidator(*gc.name); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + if v, ok := gc.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + } } - if len(gc.info) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"info\"") - } - if gc.info == nil { + if _, ok := gc.mutation.InfoID(); !ok { return nil, errors.New("ent: missing required edge \"info\"") } - return gc.gremlinSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.gremlinSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -231,39 +230,39 @@ func (gc *GroupCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 2) v := g.AddV(group.Label) - if gc.active != nil { - v.Property(dsl.Single, group.FieldActive, *gc.active) + if value, ok := gc.mutation.Active(); ok { + v.Property(dsl.Single, group.FieldActive, value) } - if gc.expire != nil { - v.Property(dsl.Single, group.FieldExpire, *gc.expire) + if value, ok := gc.mutation.Expire(); ok { + v.Property(dsl.Single, group.FieldExpire, value) } - if gc._type != nil { - v.Property(dsl.Single, group.FieldType, *gc._type) + if value, ok := gc.mutation.GetType(); ok { + v.Property(dsl.Single, group.FieldType, value) } - if gc.max_users != nil { - v.Property(dsl.Single, group.FieldMaxUsers, *gc.max_users) + if value, ok := gc.mutation.MaxUsers(); ok { + v.Property(dsl.Single, group.FieldMaxUsers, value) } - if gc.name != nil { - v.Property(dsl.Single, group.FieldName, *gc.name) + if value, ok := gc.mutation.Name(); ok { + v.Property(dsl.Single, group.FieldName, value) } - for id := range gc.files { + for _, id := range gc.mutation.FilesIDs() { v.AddE(group.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.FilesLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(group.Label, group.FilesLabel, id)), }) } - for id := range gc.blocked { + for _, id := range gc.mutation.BlockedIDs() { v.AddE(group.BlockedLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.BlockedLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(group.Label, group.BlockedLabel, id)), }) } - for id := range gc.users { + for _, id := range gc.mutation.UsersIDs() { v.AddE(user.GroupsLabel).From(g.V(id)).InV() } - for id := range gc.info { + for _, id := range gc.mutation.InfoIDs() { v.AddE(group.InfoLabel).To(g.V(id)).OutV() } if len(constraints) == 0 { diff --git a/entc/integration/gremlin/ent/group_delete.go b/entc/integration/gremlin/ent/group_delete.go index b9e9450a2..58b10d625 100644 --- a/entc/integration/gremlin/ent/group_delete.go +++ b/entc/integration/gremlin/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -31,7 +34,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.gremlinExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/group_update.go b/entc/integration/gremlin/ent/group_update.go index e0b193aa7..20ac30b06 100644 --- a/entc/integration/gremlin/ent/group_update.go +++ b/entc/integration/gremlin/ent/group_update.go @@ -25,23 +25,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - active *bool - expire *time.Time - _type *string - clear_type bool - max_users *int - addmax_users *int - clearmax_users bool - name *string - files map[string]struct{} - blocked map[string]struct{} - users map[string]struct{} - info map[string]struct{} - removedFiles map[string]struct{} - removedBlocked map[string]struct{} - removedUsers map[string]struct{} - clearedInfo bool - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -52,7 +38,7 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // SetActive sets the active field. func (gu *GroupUpdate) SetActive(b bool) *GroupUpdate { - gu.active = &b + gu.mutation.SetActive(b) return gu } @@ -66,13 +52,13 @@ func (gu *GroupUpdate) SetNillableActive(b *bool) *GroupUpdate { // SetExpire sets the expire field. func (gu *GroupUpdate) SetExpire(t time.Time) *GroupUpdate { - gu.expire = &t + gu.mutation.SetExpire(t) return gu } // SetType sets the type field. func (gu *GroupUpdate) SetType(s string) *GroupUpdate { - gu._type = &s + gu.mutation.SetType(s) return gu } @@ -86,15 +72,14 @@ func (gu *GroupUpdate) SetNillableType(s *string) *GroupUpdate { // ClearType clears the value of type. func (gu *GroupUpdate) ClearType() *GroupUpdate { - gu._type = nil - gu.clear_type = true + gu.mutation.ClearType() return gu } // SetMaxUsers sets the max_users field. func (gu *GroupUpdate) SetMaxUsers(i int) *GroupUpdate { - gu.max_users = &i - gu.addmax_users = nil + gu.mutation.ResetMaxUsers() + gu.mutation.SetMaxUsers(i) return gu } @@ -108,35 +93,25 @@ func (gu *GroupUpdate) SetNillableMaxUsers(i *int) *GroupUpdate { // AddMaxUsers adds i to max_users. func (gu *GroupUpdate) AddMaxUsers(i int) *GroupUpdate { - if gu.addmax_users == nil { - gu.addmax_users = &i - } else { - *gu.addmax_users += i - } + gu.mutation.AddMaxUsers(i) return gu } // ClearMaxUsers clears the value of max_users. func (gu *GroupUpdate) ClearMaxUsers() *GroupUpdate { - gu.max_users = nil - gu.clearmax_users = true + gu.mutation.ClearMaxUsers() return gu } // SetName sets the name field. func (gu *GroupUpdate) SetName(s string) *GroupUpdate { - gu.name = &s + gu.mutation.SetName(s) return gu } // AddFileIDs adds the files edge to File by ids. func (gu *GroupUpdate) AddFileIDs(ids ...string) *GroupUpdate { - if gu.files == nil { - gu.files = make(map[string]struct{}) - } - for i := range ids { - gu.files[ids[i]] = struct{}{} - } + gu.mutation.AddFileIDs(ids...) return gu } @@ -151,12 +126,7 @@ func (gu *GroupUpdate) AddFiles(f ...*File) *GroupUpdate { // AddBlockedIDs adds the blocked edge to User by ids. func (gu *GroupUpdate) AddBlockedIDs(ids ...string) *GroupUpdate { - if gu.blocked == nil { - gu.blocked = make(map[string]struct{}) - } - for i := range ids { - gu.blocked[ids[i]] = struct{}{} - } + gu.mutation.AddBlockedIDs(ids...) return gu } @@ -171,12 +141,7 @@ func (gu *GroupUpdate) AddBlocked(u ...*User) *GroupUpdate { // AddUserIDs adds the users edge to User by ids. func (gu *GroupUpdate) AddUserIDs(ids ...string) *GroupUpdate { - if gu.users == nil { - gu.users = make(map[string]struct{}) - } - for i := range ids { - gu.users[ids[i]] = struct{}{} - } + gu.mutation.AddUserIDs(ids...) return gu } @@ -191,10 +156,7 @@ func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { // SetInfoID sets the info edge to GroupInfo by id. func (gu *GroupUpdate) SetInfoID(id string) *GroupUpdate { - if gu.info == nil { - gu.info = make(map[string]struct{}) - } - gu.info[id] = struct{}{} + gu.mutation.SetInfoID(id) return gu } @@ -205,12 +167,7 @@ func (gu *GroupUpdate) SetInfo(g *GroupInfo) *GroupUpdate { // RemoveFileIDs removes the files edge to File by ids. func (gu *GroupUpdate) RemoveFileIDs(ids ...string) *GroupUpdate { - if gu.removedFiles == nil { - gu.removedFiles = make(map[string]struct{}) - } - for i := range ids { - gu.removedFiles[ids[i]] = struct{}{} - } + gu.mutation.RemoveFileIDs(ids...) return gu } @@ -225,12 +182,7 @@ func (gu *GroupUpdate) RemoveFiles(f ...*File) *GroupUpdate { // RemoveBlockedIDs removes the blocked edge to User by ids. func (gu *GroupUpdate) RemoveBlockedIDs(ids ...string) *GroupUpdate { - if gu.removedBlocked == nil { - gu.removedBlocked = make(map[string]struct{}) - } - for i := range ids { - gu.removedBlocked[ids[i]] = struct{}{} - } + gu.mutation.RemoveBlockedIDs(ids...) return gu } @@ -245,12 +197,7 @@ func (gu *GroupUpdate) RemoveBlocked(u ...*User) *GroupUpdate { // RemoveUserIDs removes the users edge to User by ids. func (gu *GroupUpdate) RemoveUserIDs(ids ...string) *GroupUpdate { - if gu.removedUsers == nil { - gu.removedUsers = make(map[string]struct{}) - } - for i := range ids { - gu.removedUsers[ids[i]] = struct{}{} - } + gu.mutation.RemoveUserIDs(ids...) return gu } @@ -265,34 +212,55 @@ func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { // ClearInfo clears the info edge to GroupInfo. func (gu *GroupUpdate) ClearInfo() *GroupUpdate { - gu.clearedInfo = true + gu.mutation.ClearInfo() return gu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - if gu._type != nil { - if err := group.TypeValidator(*gu._type); err != nil { + if v, ok := gu.mutation.GetType(); ok { + if err := group.TypeValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"type\": %v", err) } } - if gu.max_users != nil { - if err := group.MaxUsersValidator(*gu.max_users); err != nil { + if v, ok := gu.mutation.MaxUsers(); ok { + if err := group.MaxUsersValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) } } - if gu.name != nil { - if err := group.NameValidator(*gu.name); err != nil { + if v, ok := gu.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(gu.info) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"info\"") - } - if gu.clearedInfo && gu.info == nil { + + if _, ok := gu.mutation.InfoID(); gu.mutation.InfoCleared() && !ok { return 0, errors.New("ent: clearing a unique edge \"info\"") } - return gu.gremlinSave(ctx) + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.gremlinSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -345,68 +313,68 @@ func (gu *GroupUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := gu.active; value != nil { - v.Property(dsl.Single, group.FieldActive, *value) + if value, ok := gu.mutation.Active(); ok { + v.Property(dsl.Single, group.FieldActive, value) } - if value := gu.expire; value != nil { - v.Property(dsl.Single, group.FieldExpire, *value) + if value, ok := gu.mutation.Expire(); ok { + v.Property(dsl.Single, group.FieldExpire, value) } - if value := gu._type; value != nil { - v.Property(dsl.Single, group.FieldType, *value) + if value, ok := gu.mutation.GetType(); ok { + v.Property(dsl.Single, group.FieldType, value) } - if value := gu.max_users; value != nil { - v.Property(dsl.Single, group.FieldMaxUsers, *value) + if value, ok := gu.mutation.MaxUsers(); ok { + v.Property(dsl.Single, group.FieldMaxUsers, value) } - if value := gu.addmax_users; value != nil { - v.Property(dsl.Single, group.FieldMaxUsers, __.Union(__.Values(group.FieldMaxUsers), __.Constant(*value)).Sum()) + if value, ok := gu.mutation.AddedMaxUsers(); ok { + v.Property(dsl.Single, group.FieldMaxUsers, __.Union(__.Values(group.FieldMaxUsers), __.Constant(value)).Sum()) } - if value := gu.name; value != nil { - v.Property(dsl.Single, group.FieldName, *value) + if value, ok := gu.mutation.Name(); ok { + v.Property(dsl.Single, group.FieldName, value) } var properties []interface{} - if gu.clear_type { + if gu.mutation.TypeCleared() { properties = append(properties, group.FieldType) } - if gu.clearmax_users { + if gu.mutation.MaxUsersCleared() { properties = append(properties, group.FieldMaxUsers) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - for id := range gu.removedFiles { + for _, id := range gu.mutation.RemovedFilesIDs() { tr := rv.Clone().OutE(group.FilesLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range gu.files { + for _, id := range gu.mutation.FilesIDs() { v.AddE(group.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.FilesLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(group.Label, group.FilesLabel, id)), }) } - for id := range gu.removedBlocked { + for _, id := range gu.mutation.RemovedBlockedIDs() { tr := rv.Clone().OutE(group.BlockedLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range gu.blocked { + for _, id := range gu.mutation.BlockedIDs() { v.AddE(group.BlockedLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.BlockedLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(group.Label, group.BlockedLabel, id)), }) } - for id := range gu.removedUsers { + for _, id := range gu.mutation.RemovedUsersIDs() { tr := rv.Clone().InE(user.GroupsLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range gu.users { + for _, id := range gu.mutation.UsersIDs() { v.AddE(user.GroupsLabel).From(g.V(id)).InV() } - if gu.clearedInfo { + if gu.mutation.InfoCleared() { tr := rv.Clone().OutE(group.InfoLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range gu.info { + for _, id := range gu.mutation.InfoIDs() { v.AddE(group.InfoLabel).To(g.V(id)).OutV() } v.Count() @@ -427,28 +395,13 @@ func (gu *GroupUpdate) gremlin() *dsl.Traversal { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id string - active *bool - expire *time.Time - _type *string - clear_type bool - max_users *int - addmax_users *int - clearmax_users bool - name *string - files map[string]struct{} - blocked map[string]struct{} - users map[string]struct{} - info map[string]struct{} - removedFiles map[string]struct{} - removedBlocked map[string]struct{} - removedUsers map[string]struct{} - clearedInfo bool + hooks []Hook + mutation *GroupMutation } // SetActive sets the active field. func (guo *GroupUpdateOne) SetActive(b bool) *GroupUpdateOne { - guo.active = &b + guo.mutation.SetActive(b) return guo } @@ -462,13 +415,13 @@ func (guo *GroupUpdateOne) SetNillableActive(b *bool) *GroupUpdateOne { // SetExpire sets the expire field. func (guo *GroupUpdateOne) SetExpire(t time.Time) *GroupUpdateOne { - guo.expire = &t + guo.mutation.SetExpire(t) return guo } // SetType sets the type field. func (guo *GroupUpdateOne) SetType(s string) *GroupUpdateOne { - guo._type = &s + guo.mutation.SetType(s) return guo } @@ -482,15 +435,14 @@ func (guo *GroupUpdateOne) SetNillableType(s *string) *GroupUpdateOne { // ClearType clears the value of type. func (guo *GroupUpdateOne) ClearType() *GroupUpdateOne { - guo._type = nil - guo.clear_type = true + guo.mutation.ClearType() return guo } // SetMaxUsers sets the max_users field. func (guo *GroupUpdateOne) SetMaxUsers(i int) *GroupUpdateOne { - guo.max_users = &i - guo.addmax_users = nil + guo.mutation.ResetMaxUsers() + guo.mutation.SetMaxUsers(i) return guo } @@ -504,35 +456,25 @@ func (guo *GroupUpdateOne) SetNillableMaxUsers(i *int) *GroupUpdateOne { // AddMaxUsers adds i to max_users. func (guo *GroupUpdateOne) AddMaxUsers(i int) *GroupUpdateOne { - if guo.addmax_users == nil { - guo.addmax_users = &i - } else { - *guo.addmax_users += i - } + guo.mutation.AddMaxUsers(i) return guo } // ClearMaxUsers clears the value of max_users. func (guo *GroupUpdateOne) ClearMaxUsers() *GroupUpdateOne { - guo.max_users = nil - guo.clearmax_users = true + guo.mutation.ClearMaxUsers() return guo } // SetName sets the name field. func (guo *GroupUpdateOne) SetName(s string) *GroupUpdateOne { - guo.name = &s + guo.mutation.SetName(s) return guo } // AddFileIDs adds the files edge to File by ids. func (guo *GroupUpdateOne) AddFileIDs(ids ...string) *GroupUpdateOne { - if guo.files == nil { - guo.files = make(map[string]struct{}) - } - for i := range ids { - guo.files[ids[i]] = struct{}{} - } + guo.mutation.AddFileIDs(ids...) return guo } @@ -547,12 +489,7 @@ func (guo *GroupUpdateOne) AddFiles(f ...*File) *GroupUpdateOne { // AddBlockedIDs adds the blocked edge to User by ids. func (guo *GroupUpdateOne) AddBlockedIDs(ids ...string) *GroupUpdateOne { - if guo.blocked == nil { - guo.blocked = make(map[string]struct{}) - } - for i := range ids { - guo.blocked[ids[i]] = struct{}{} - } + guo.mutation.AddBlockedIDs(ids...) return guo } @@ -567,12 +504,7 @@ func (guo *GroupUpdateOne) AddBlocked(u ...*User) *GroupUpdateOne { // AddUserIDs adds the users edge to User by ids. func (guo *GroupUpdateOne) AddUserIDs(ids ...string) *GroupUpdateOne { - if guo.users == nil { - guo.users = make(map[string]struct{}) - } - for i := range ids { - guo.users[ids[i]] = struct{}{} - } + guo.mutation.AddUserIDs(ids...) return guo } @@ -587,10 +519,7 @@ func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { // SetInfoID sets the info edge to GroupInfo by id. func (guo *GroupUpdateOne) SetInfoID(id string) *GroupUpdateOne { - if guo.info == nil { - guo.info = make(map[string]struct{}) - } - guo.info[id] = struct{}{} + guo.mutation.SetInfoID(id) return guo } @@ -601,12 +530,7 @@ func (guo *GroupUpdateOne) SetInfo(g *GroupInfo) *GroupUpdateOne { // RemoveFileIDs removes the files edge to File by ids. func (guo *GroupUpdateOne) RemoveFileIDs(ids ...string) *GroupUpdateOne { - if guo.removedFiles == nil { - guo.removedFiles = make(map[string]struct{}) - } - for i := range ids { - guo.removedFiles[ids[i]] = struct{}{} - } + guo.mutation.RemoveFileIDs(ids...) return guo } @@ -621,12 +545,7 @@ func (guo *GroupUpdateOne) RemoveFiles(f ...*File) *GroupUpdateOne { // RemoveBlockedIDs removes the blocked edge to User by ids. func (guo *GroupUpdateOne) RemoveBlockedIDs(ids ...string) *GroupUpdateOne { - if guo.removedBlocked == nil { - guo.removedBlocked = make(map[string]struct{}) - } - for i := range ids { - guo.removedBlocked[ids[i]] = struct{}{} - } + guo.mutation.RemoveBlockedIDs(ids...) return guo } @@ -641,12 +560,7 @@ func (guo *GroupUpdateOne) RemoveBlocked(u ...*User) *GroupUpdateOne { // RemoveUserIDs removes the users edge to User by ids. func (guo *GroupUpdateOne) RemoveUserIDs(ids ...string) *GroupUpdateOne { - if guo.removedUsers == nil { - guo.removedUsers = make(map[string]struct{}) - } - for i := range ids { - guo.removedUsers[ids[i]] = struct{}{} - } + guo.mutation.RemoveUserIDs(ids...) return guo } @@ -661,34 +575,55 @@ func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { // ClearInfo clears the info edge to GroupInfo. func (guo *GroupUpdateOne) ClearInfo() *GroupUpdateOne { - guo.clearedInfo = true + guo.mutation.ClearInfo() return guo } // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - if guo._type != nil { - if err := group.TypeValidator(*guo._type); err != nil { + if v, ok := guo.mutation.GetType(); ok { + if err := group.TypeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"type\": %v", err) } } - if guo.max_users != nil { - if err := group.MaxUsersValidator(*guo.max_users); err != nil { + if v, ok := guo.mutation.MaxUsers(); ok { + if err := group.MaxUsersValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"max_users\": %v", err) } } - if guo.name != nil { - if err := group.NameValidator(*guo.name); err != nil { + if v, ok := guo.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - if len(guo.info) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"info\"") - } - if guo.clearedInfo && guo.info == nil { + + if _, ok := guo.mutation.InfoID(); guo.mutation.InfoCleared() && !ok { return nil, errors.New("ent: clearing a unique edge \"info\"") } - return guo.gremlinSave(ctx) + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.gremlinSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -715,7 +650,11 @@ func (guo *GroupUpdateOne) ExecX(ctx context.Context) { func (guo *GroupUpdateOne) gremlinSave(ctx context.Context) (*Group, error) { res := &gremlin.Response{} - query, bindings := guo.gremlin(guo.id).Query() + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + query, bindings := guo.gremlin(id).Query() if err := guo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -742,68 +681,68 @@ func (guo *GroupUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := guo.active; value != nil { - v.Property(dsl.Single, group.FieldActive, *value) + if value, ok := guo.mutation.Active(); ok { + v.Property(dsl.Single, group.FieldActive, value) } - if value := guo.expire; value != nil { - v.Property(dsl.Single, group.FieldExpire, *value) + if value, ok := guo.mutation.Expire(); ok { + v.Property(dsl.Single, group.FieldExpire, value) } - if value := guo._type; value != nil { - v.Property(dsl.Single, group.FieldType, *value) + if value, ok := guo.mutation.GetType(); ok { + v.Property(dsl.Single, group.FieldType, value) } - if value := guo.max_users; value != nil { - v.Property(dsl.Single, group.FieldMaxUsers, *value) + if value, ok := guo.mutation.MaxUsers(); ok { + v.Property(dsl.Single, group.FieldMaxUsers, value) } - if value := guo.addmax_users; value != nil { - v.Property(dsl.Single, group.FieldMaxUsers, __.Union(__.Values(group.FieldMaxUsers), __.Constant(*value)).Sum()) + if value, ok := guo.mutation.AddedMaxUsers(); ok { + v.Property(dsl.Single, group.FieldMaxUsers, __.Union(__.Values(group.FieldMaxUsers), __.Constant(value)).Sum()) } - if value := guo.name; value != nil { - v.Property(dsl.Single, group.FieldName, *value) + if value, ok := guo.mutation.Name(); ok { + v.Property(dsl.Single, group.FieldName, value) } var properties []interface{} - if guo.clear_type { + if guo.mutation.TypeCleared() { properties = append(properties, group.FieldType) } - if guo.clearmax_users { + if guo.mutation.MaxUsersCleared() { properties = append(properties, group.FieldMaxUsers) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - for id := range guo.removedFiles { + for _, id := range guo.mutation.RemovedFilesIDs() { tr := rv.Clone().OutE(group.FilesLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range guo.files { + for _, id := range guo.mutation.FilesIDs() { v.AddE(group.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.FilesLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(group.Label, group.FilesLabel, id)), }) } - for id := range guo.removedBlocked { + for _, id := range guo.mutation.RemovedBlockedIDs() { tr := rv.Clone().OutE(group.BlockedLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range guo.blocked { + for _, id := range guo.mutation.BlockedIDs() { v.AddE(group.BlockedLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.BlockedLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(group.Label, group.BlockedLabel, id)), }) } - for id := range guo.removedUsers { + for _, id := range guo.mutation.RemovedUsersIDs() { tr := rv.Clone().InE(user.GroupsLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range guo.users { + for _, id := range guo.mutation.UsersIDs() { v.AddE(user.GroupsLabel).From(g.V(id)).InV() } - if guo.clearedInfo { + if guo.mutation.InfoCleared() { tr := rv.Clone().OutE(group.InfoLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range guo.info { + for _, id := range guo.mutation.InfoIDs() { v.AddE(group.InfoLabel).To(g.V(id)).OutV() } v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/groupinfo/groupinfo.go b/entc/integration/gremlin/ent/groupinfo/groupinfo.go index 31cba7bd9..1a5d841e7 100644 --- a/entc/integration/gremlin/ent/groupinfo/groupinfo.go +++ b/entc/integration/gremlin/ent/groupinfo/groupinfo.go @@ -6,29 +6,22 @@ package groupinfo -import ( - "github.com/facebookincubator/ent/entc/integration/ent/schema" -) - const ( // Label holds the string label denoting the groupinfo type in the database. Label = "group_info" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldDesc holds the string denoting the desc vertex property in the database. - FieldDesc = "desc" - // FieldMaxUsers holds the string denoting the max_users vertex property in the database. + FieldID = "id" // FieldDesc holds the string denoting the desc vertex property in the database. + FieldDesc = "desc" // FieldMaxUsers holds the string denoting the max_users vertex property in the database. FieldMaxUsers = "max_users" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // GroupsInverseLabel holds the string label denoting the groups inverse edge type in the database. GroupsInverseLabel = "group_info" ) var ( - fields = schema.GroupInfo{}.Fields() - - // descMaxUsers is the schema descriptor for max_users field. - descMaxUsers = fields[1].Descriptor() // DefaultMaxUsers holds the default value on creation for the max_users field. - DefaultMaxUsers = descMaxUsers.Default.(int) + DefaultMaxUsers int ) diff --git a/entc/integration/gremlin/ent/groupinfo_create.go b/entc/integration/gremlin/ent/groupinfo_create.go index f3ea62674..f47c05105 100644 --- a/entc/integration/gremlin/ent/groupinfo_create.go +++ b/entc/integration/gremlin/ent/groupinfo_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -22,20 +23,19 @@ import ( // GroupInfoCreate is the builder for creating a GroupInfo entity. type GroupInfoCreate struct { config - desc *string - max_users *int - groups map[string]struct{} + mutation *GroupInfoMutation + hooks []Hook } // SetDesc sets the desc field. func (gic *GroupInfoCreate) SetDesc(s string) *GroupInfoCreate { - gic.desc = &s + gic.mutation.SetDesc(s) return gic } // SetMaxUsers sets the max_users field. func (gic *GroupInfoCreate) SetMaxUsers(i int) *GroupInfoCreate { - gic.max_users = &i + gic.mutation.SetMaxUsers(i) return gic } @@ -49,12 +49,7 @@ func (gic *GroupInfoCreate) SetNillableMaxUsers(i *int) *GroupInfoCreate { // AddGroupIDs adds the groups edge to Group by ids. func (gic *GroupInfoCreate) AddGroupIDs(ids ...string) *GroupInfoCreate { - if gic.groups == nil { - gic.groups = make(map[string]struct{}) - } - for i := range ids { - gic.groups[ids[i]] = struct{}{} - } + gic.mutation.AddGroupIDs(ids...) return gic } @@ -69,14 +64,37 @@ func (gic *GroupInfoCreate) AddGroups(g ...*Group) *GroupInfoCreate { // Save creates the GroupInfo in the database. func (gic *GroupInfoCreate) Save(ctx context.Context) (*GroupInfo, error) { - if gic.desc == nil { + if _, ok := gic.mutation.Desc(); !ok { return nil, errors.New("ent: missing required field \"desc\"") } - if gic.max_users == nil { + if _, ok := gic.mutation.MaxUsers(); !ok { v := groupinfo.DefaultMaxUsers - gic.max_users = &v + gic.mutation.SetMaxUsers(v) } - return gic.gremlinSave(ctx) + var ( + err error + node *GroupInfo + ) + if len(gic.hooks) == 0 { + node, err = gic.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gic.mutation = mutation + node, err = gic.gremlinSave(ctx) + return node, err + }) + for i := len(gic.hooks); i > 0; i-- { + mut = gic.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gic.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -111,13 +129,13 @@ func (gic *GroupInfoCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 1) v := g.AddV(groupinfo.Label) - if gic.desc != nil { - v.Property(dsl.Single, groupinfo.FieldDesc, *gic.desc) + if value, ok := gic.mutation.Desc(); ok { + v.Property(dsl.Single, groupinfo.FieldDesc, value) } - if gic.max_users != nil { - v.Property(dsl.Single, groupinfo.FieldMaxUsers, *gic.max_users) + if value, ok := gic.mutation.MaxUsers(); ok { + v.Property(dsl.Single, groupinfo.FieldMaxUsers, value) } - for id := range gic.groups { + for _, id := range gic.mutation.GroupsIDs() { v.AddE(group.InfoLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.InfoLabel).OutV().HasID(id).Count(), diff --git a/entc/integration/gremlin/ent/groupinfo_delete.go b/entc/integration/gremlin/ent/groupinfo_delete.go index 051fafe66..e63ebb7ca 100644 --- a/entc/integration/gremlin/ent/groupinfo_delete.go +++ b/entc/integration/gremlin/ent/groupinfo_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // GroupInfoDelete is the builder for deleting a GroupInfo entity. type GroupInfoDelete struct { config + hooks []Hook + mutation *GroupInfoMutation predicates []predicate.GroupInfo } @@ -31,7 +34,30 @@ func (gid *GroupInfoDelete) Where(ps ...predicate.GroupInfo) *GroupInfoDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gid *GroupInfoDelete) Exec(ctx context.Context) (int, error) { - return gid.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(gid.hooks) == 0 { + affected, err = gid.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gid.mutation = mutation + affected, err = gid.gremlinExec(ctx) + return affected, err + }) + for i := len(gid.hooks); i > 0; i-- { + mut = gid.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gid.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/groupinfo_update.go b/entc/integration/gremlin/ent/groupinfo_update.go index 5ba5e6a2c..274437572 100644 --- a/entc/integration/gremlin/ent/groupinfo_update.go +++ b/entc/integration/gremlin/ent/groupinfo_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -22,12 +23,9 @@ import ( // GroupInfoUpdate is the builder for updating GroupInfo entities. type GroupInfoUpdate struct { config - desc *string - max_users *int - addmax_users *int - groups map[string]struct{} - removedGroups map[string]struct{} - predicates []predicate.GroupInfo + hooks []Hook + mutation *GroupInfoMutation + predicates []predicate.GroupInfo } // Where adds a new predicate for the builder. @@ -38,14 +36,14 @@ func (giu *GroupInfoUpdate) Where(ps ...predicate.GroupInfo) *GroupInfoUpdate { // SetDesc sets the desc field. func (giu *GroupInfoUpdate) SetDesc(s string) *GroupInfoUpdate { - giu.desc = &s + giu.mutation.SetDesc(s) return giu } // SetMaxUsers sets the max_users field. func (giu *GroupInfoUpdate) SetMaxUsers(i int) *GroupInfoUpdate { - giu.max_users = &i - giu.addmax_users = nil + giu.mutation.ResetMaxUsers() + giu.mutation.SetMaxUsers(i) return giu } @@ -59,22 +57,13 @@ func (giu *GroupInfoUpdate) SetNillableMaxUsers(i *int) *GroupInfoUpdate { // AddMaxUsers adds i to max_users. func (giu *GroupInfoUpdate) AddMaxUsers(i int) *GroupInfoUpdate { - if giu.addmax_users == nil { - giu.addmax_users = &i - } else { - *giu.addmax_users += i - } + giu.mutation.AddMaxUsers(i) return giu } // AddGroupIDs adds the groups edge to Group by ids. func (giu *GroupInfoUpdate) AddGroupIDs(ids ...string) *GroupInfoUpdate { - if giu.groups == nil { - giu.groups = make(map[string]struct{}) - } - for i := range ids { - giu.groups[ids[i]] = struct{}{} - } + giu.mutation.AddGroupIDs(ids...) return giu } @@ -89,12 +78,7 @@ func (giu *GroupInfoUpdate) AddGroups(g ...*Group) *GroupInfoUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (giu *GroupInfoUpdate) RemoveGroupIDs(ids ...string) *GroupInfoUpdate { - if giu.removedGroups == nil { - giu.removedGroups = make(map[string]struct{}) - } - for i := range ids { - giu.removedGroups[ids[i]] = struct{}{} - } + giu.mutation.RemoveGroupIDs(ids...) return giu } @@ -109,7 +93,31 @@ func (giu *GroupInfoUpdate) RemoveGroups(g ...*Group) *GroupInfoUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (giu *GroupInfoUpdate) Save(ctx context.Context) (int, error) { - return giu.gremlinSave(ctx) + + var ( + err error + affected int + ) + if len(giu.hooks) == 0 { + affected, err = giu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + giu.mutation = mutation + affected, err = giu.gremlinSave(ctx) + return affected, err + }) + for i := len(giu.hooks); i > 0; i-- { + mut = giu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, giu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -162,20 +170,20 @@ func (giu *GroupInfoUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := giu.desc; value != nil { - v.Property(dsl.Single, groupinfo.FieldDesc, *value) + if value, ok := giu.mutation.Desc(); ok { + v.Property(dsl.Single, groupinfo.FieldDesc, value) } - if value := giu.max_users; value != nil { - v.Property(dsl.Single, groupinfo.FieldMaxUsers, *value) + if value, ok := giu.mutation.MaxUsers(); ok { + v.Property(dsl.Single, groupinfo.FieldMaxUsers, value) } - if value := giu.addmax_users; value != nil { - v.Property(dsl.Single, groupinfo.FieldMaxUsers, __.Union(__.Values(groupinfo.FieldMaxUsers), __.Constant(*value)).Sum()) + if value, ok := giu.mutation.AddedMaxUsers(); ok { + v.Property(dsl.Single, groupinfo.FieldMaxUsers, __.Union(__.Values(groupinfo.FieldMaxUsers), __.Constant(value)).Sum()) } - for id := range giu.removedGroups { + for _, id := range giu.mutation.RemovedGroupsIDs() { tr := rv.Clone().InE(group.InfoLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range giu.groups { + for _, id := range giu.mutation.GroupsIDs() { v.AddE(group.InfoLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.InfoLabel).OutV().HasID(id).Count(), @@ -200,24 +208,20 @@ func (giu *GroupInfoUpdate) gremlin() *dsl.Traversal { // GroupInfoUpdateOne is the builder for updating a single GroupInfo entity. type GroupInfoUpdateOne struct { config - id string - desc *string - max_users *int - addmax_users *int - groups map[string]struct{} - removedGroups map[string]struct{} + hooks []Hook + mutation *GroupInfoMutation } // SetDesc sets the desc field. func (giuo *GroupInfoUpdateOne) SetDesc(s string) *GroupInfoUpdateOne { - giuo.desc = &s + giuo.mutation.SetDesc(s) return giuo } // SetMaxUsers sets the max_users field. func (giuo *GroupInfoUpdateOne) SetMaxUsers(i int) *GroupInfoUpdateOne { - giuo.max_users = &i - giuo.addmax_users = nil + giuo.mutation.ResetMaxUsers() + giuo.mutation.SetMaxUsers(i) return giuo } @@ -231,22 +235,13 @@ func (giuo *GroupInfoUpdateOne) SetNillableMaxUsers(i *int) *GroupInfoUpdateOne // AddMaxUsers adds i to max_users. func (giuo *GroupInfoUpdateOne) AddMaxUsers(i int) *GroupInfoUpdateOne { - if giuo.addmax_users == nil { - giuo.addmax_users = &i - } else { - *giuo.addmax_users += i - } + giuo.mutation.AddMaxUsers(i) return giuo } // AddGroupIDs adds the groups edge to Group by ids. func (giuo *GroupInfoUpdateOne) AddGroupIDs(ids ...string) *GroupInfoUpdateOne { - if giuo.groups == nil { - giuo.groups = make(map[string]struct{}) - } - for i := range ids { - giuo.groups[ids[i]] = struct{}{} - } + giuo.mutation.AddGroupIDs(ids...) return giuo } @@ -261,12 +256,7 @@ func (giuo *GroupInfoUpdateOne) AddGroups(g ...*Group) *GroupInfoUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (giuo *GroupInfoUpdateOne) RemoveGroupIDs(ids ...string) *GroupInfoUpdateOne { - if giuo.removedGroups == nil { - giuo.removedGroups = make(map[string]struct{}) - } - for i := range ids { - giuo.removedGroups[ids[i]] = struct{}{} - } + giuo.mutation.RemoveGroupIDs(ids...) return giuo } @@ -281,7 +271,31 @@ func (giuo *GroupInfoUpdateOne) RemoveGroups(g ...*Group) *GroupInfoUpdateOne { // Save executes the query and returns the updated entity. func (giuo *GroupInfoUpdateOne) Save(ctx context.Context) (*GroupInfo, error) { - return giuo.gremlinSave(ctx) + + var ( + err error + node *GroupInfo + ) + if len(giuo.hooks) == 0 { + node, err = giuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + giuo.mutation = mutation + node, err = giuo.gremlinSave(ctx) + return node, err + }) + for i := len(giuo.hooks); i > 0; i-- { + mut = giuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, giuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -308,7 +322,11 @@ func (giuo *GroupInfoUpdateOne) ExecX(ctx context.Context) { func (giuo *GroupInfoUpdateOne) gremlinSave(ctx context.Context) (*GroupInfo, error) { res := &gremlin.Response{} - query, bindings := giuo.gremlin(giuo.id).Query() + id, ok := giuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing GroupInfo.ID for update") + } + query, bindings := giuo.gremlin(id).Query() if err := giuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -335,20 +353,20 @@ func (giuo *GroupInfoUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := giuo.desc; value != nil { - v.Property(dsl.Single, groupinfo.FieldDesc, *value) + if value, ok := giuo.mutation.Desc(); ok { + v.Property(dsl.Single, groupinfo.FieldDesc, value) } - if value := giuo.max_users; value != nil { - v.Property(dsl.Single, groupinfo.FieldMaxUsers, *value) + if value, ok := giuo.mutation.MaxUsers(); ok { + v.Property(dsl.Single, groupinfo.FieldMaxUsers, value) } - if value := giuo.addmax_users; value != nil { - v.Property(dsl.Single, groupinfo.FieldMaxUsers, __.Union(__.Values(groupinfo.FieldMaxUsers), __.Constant(*value)).Sum()) + if value, ok := giuo.mutation.AddedMaxUsers(); ok { + v.Property(dsl.Single, groupinfo.FieldMaxUsers, __.Union(__.Values(groupinfo.FieldMaxUsers), __.Constant(value)).Sum()) } - for id := range giuo.removedGroups { + for _, id := range giuo.mutation.RemovedGroupsIDs() { tr := rv.Clone().InE(group.InfoLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range giuo.groups { + for _, id := range giuo.mutation.GroupsIDs() { v.AddE(group.InfoLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(group.InfoLabel).OutV().HasID(id).Count(), diff --git a/entc/integration/gremlin/ent/hook/hook.go b/entc/integration/gremlin/ent/hook/hook.go new file mode 100644 index 000000000..d56cde064 --- /dev/null +++ b/entc/integration/gremlin/ent/hook/hook.go @@ -0,0 +1,204 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/gremlin/ent" +) + +// The CardFunc type is an adapter to allow the use of ordinary +// function as Card mutator. +type CardFunc func(context.Context, *ent.CardMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CardFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CardMutation", m) + } + return f(ctx, mv) +} + +// The CommentFunc type is an adapter to allow the use of ordinary +// function as Comment mutator. +type CommentFunc func(context.Context, *ent.CommentMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CommentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CommentMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CommentMutation", m) + } + return f(ctx, mv) +} + +// The FieldTypeFunc type is an adapter to allow the use of ordinary +// function as FieldType mutator. +type FieldTypeFunc func(context.Context, *ent.FieldTypeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f FieldTypeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.FieldTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FieldTypeMutation", m) + } + return f(ctx, mv) +} + +// The FileFunc type is an adapter to allow the use of ordinary +// function as File mutator. +type FileFunc func(context.Context, *ent.FileMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f FileFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.FileMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FileMutation", m) + } + return f(ctx, mv) +} + +// The FileTypeFunc type is an adapter to allow the use of ordinary +// function as FileType mutator. +type FileTypeFunc func(context.Context, *ent.FileTypeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f FileTypeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.FileTypeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FileTypeMutation", m) + } + return f(ctx, mv) +} + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The GroupInfoFunc type is an adapter to allow the use of ordinary +// function as GroupInfo mutator. +type GroupInfoFunc func(context.Context, *ent.GroupInfoMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupInfoFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupInfoMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupInfoMutation", m) + } + return f(ctx, mv) +} + +// The ItemFunc type is an adapter to allow the use of ordinary +// function as Item mutator. +type ItemFunc func(context.Context, *ent.ItemMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f ItemFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ItemMutation", m) + } + return f(ctx, mv) +} + +// The NodeFunc type is an adapter to allow the use of ordinary +// function as Node mutator. +type NodeFunc func(context.Context, *ent.NodeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f NodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.NodeMutation", m) + } + return f(ctx, mv) +} + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The SpecFunc type is an adapter to allow the use of ordinary +// function as Spec mutator. +type SpecFunc func(context.Context, *ent.SpecMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f SpecFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SpecMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/gremlin/ent/item_create.go b/entc/integration/gremlin/ent/item_create.go index 8e45ffc06..6ee9570a8 100644 --- a/entc/integration/gremlin/ent/item_create.go +++ b/entc/integration/gremlin/ent/item_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -18,11 +19,36 @@ import ( // ItemCreate is the builder for creating a Item entity. type ItemCreate struct { config + mutation *ItemMutation + hooks []Hook } // Save creates the Item in the database. func (ic *ItemCreate) Save(ctx context.Context) (*Item, error) { - return ic.gremlinSave(ctx) + var ( + err error + node *Item + ) + if len(ic.hooks) == 0 { + node, err = ic.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ic.mutation = mutation + node, err = ic.gremlinSave(ctx) + return node, err + }) + for i := len(ic.hooks); i > 0; i-- { + mut = ic.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ic.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. diff --git a/entc/integration/gremlin/ent/item_delete.go b/entc/integration/gremlin/ent/item_delete.go index 629006a77..b551805d3 100644 --- a/entc/integration/gremlin/ent/item_delete.go +++ b/entc/integration/gremlin/ent/item_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // ItemDelete is the builder for deleting a Item entity. type ItemDelete struct { config + hooks []Hook + mutation *ItemMutation predicates []predicate.Item } @@ -31,7 +34,30 @@ func (id *ItemDelete) Where(ps ...predicate.Item) *ItemDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (id *ItemDelete) Exec(ctx context.Context) (int, error) { - return id.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(id.hooks) == 0 { + affected, err = id.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + id.mutation = mutation + affected, err = id.gremlinExec(ctx) + return affected, err + }) + for i := len(id.hooks); i > 0; i-- { + mut = id.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, id.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/item_update.go b/entc/integration/gremlin/ent/item_update.go index 827ad6d6d..c3342075d 100644 --- a/entc/integration/gremlin/ent/item_update.go +++ b/entc/integration/gremlin/ent/item_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -19,6 +20,8 @@ import ( // ItemUpdate is the builder for updating Item entities. type ItemUpdate struct { config + hooks []Hook + mutation *ItemMutation predicates []predicate.Item } @@ -30,7 +33,30 @@ func (iu *ItemUpdate) Where(ps ...predicate.Item) *ItemUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (iu *ItemUpdate) Save(ctx context.Context) (int, error) { - return iu.gremlinSave(ctx) + var ( + err error + affected int + ) + if len(iu.hooks) == 0 { + affected, err = iu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + iu.mutation = mutation + affected, err = iu.gremlinSave(ctx) + return affected, err + }) + for i := len(iu.hooks); i > 0; i-- { + mut = iu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, iu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -83,12 +109,36 @@ func (iu *ItemUpdate) gremlin() *dsl.Traversal { // ItemUpdateOne is the builder for updating a single Item entity. type ItemUpdateOne struct { config - id string + hooks []Hook + mutation *ItemMutation } // Save executes the query and returns the updated entity. func (iuo *ItemUpdateOne) Save(ctx context.Context) (*Item, error) { - return iuo.gremlinSave(ctx) + var ( + err error + node *Item + ) + if len(iuo.hooks) == 0 { + node, err = iuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ItemMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + iuo.mutation = mutation + node, err = iuo.gremlinSave(ctx) + return node, err + }) + for i := len(iuo.hooks); i > 0; i-- { + mut = iuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, iuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -115,7 +165,11 @@ func (iuo *ItemUpdateOne) ExecX(ctx context.Context) { func (iuo *ItemUpdateOne) gremlinSave(ctx context.Context) (*Item, error) { res := &gremlin.Response{} - query, bindings := iuo.gremlin(iuo.id).Query() + id, ok := iuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Item.ID for update") + } + query, bindings := iuo.gremlin(id).Query() if err := iuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } diff --git a/entc/integration/gremlin/ent/mutation.go b/entc/integration/gremlin/ent/mutation.go new file mode 100644 index 000000000..f41f7e6b6 --- /dev/null +++ b/entc/integration/gremlin/ent/mutation.go @@ -0,0 +1,7539 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "time" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/card" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/comment" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/fieldtype" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/file" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/filetype" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/group" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/groupinfo" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/node" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/pet" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/spec" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCard = "Card" + TypeComment = "Comment" + TypeFieldType = "FieldType" + TypeFile = "File" + TypeFileType = "FileType" + TypeGroup = "Group" + TypeGroupInfo = "GroupInfo" + TypeItem = "Item" + TypeNode = "Node" + TypePet = "Pet" + TypeSpec = "Spec" + TypeUser = "User" +) + +// CardMutation represents an operation that mutate the Cards +// nodes in the graph. +type CardMutation struct { + config + op Op + typ string + id *string + create_time *time.Time + update_time *time.Time + number *string + name *string + clearedFields map[string]bool + owner *string + clearedowner bool + spec map[string]struct{} + removedspec map[string]struct{} +} + +var _ ent.Mutation = (*CardMutation)(nil) + +// newCardMutation creates new mutation for $n.Name. +func newCardMutation(c config, op Op) *CardMutation { + return &CardMutation{ + config: c, + op: op, + typ: TypeCard, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CardMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CardMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CardMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetCreateTime sets the create_time field. +func (m *CardMutation) SetCreateTime(t time.Time) { + m.create_time = &t +} + +// CreateTime returns the create_time value in the mutation. +func (m *CardMutation) CreateTime() (r time.Time, exists bool) { + v := m.create_time + if v == nil { + return + } + return *v, true +} + +// ResetCreateTime reset all changes of the create_time field. +func (m *CardMutation) ResetCreateTime() { + m.create_time = nil +} + +// SetUpdateTime sets the update_time field. +func (m *CardMutation) SetUpdateTime(t time.Time) { + m.update_time = &t +} + +// UpdateTime returns the update_time value in the mutation. +func (m *CardMutation) UpdateTime() (r time.Time, exists bool) { + v := m.update_time + if v == nil { + return + } + return *v, true +} + +// ResetUpdateTime reset all changes of the update_time field. +func (m *CardMutation) ResetUpdateTime() { + m.update_time = nil +} + +// SetNumber sets the number field. +func (m *CardMutation) SetNumber(s string) { + m.number = &s +} + +// Number returns the number value in the mutation. +func (m *CardMutation) Number() (r string, exists bool) { + v := m.number + if v == nil { + return + } + return *v, true +} + +// ResetNumber reset all changes of the number field. +func (m *CardMutation) ResetNumber() { + m.number = nil +} + +// SetName sets the name field. +func (m *CardMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *CardMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ClearName clears the value of name. +func (m *CardMutation) ClearName() { + m.name = nil + m.clearedFields[card.FieldName] = true +} + +// NameCleared returns if the field name was cleared in this mutation. +func (m *CardMutation) NameCleared() bool { + return m.clearedFields[card.FieldName] +} + +// ResetName reset all changes of the name field. +func (m *CardMutation) ResetName() { + m.name = nil + delete(m.clearedFields, card.FieldName) +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CardMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CardMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CardMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CardMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CardMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CardMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// AddSpecIDs adds the spec edge to Spec by ids. +func (m *CardMutation) AddSpecIDs(ids ...string) { + if m.spec == nil { + m.spec = make(map[string]struct{}) + } + for i := range ids { + m.spec[ids[i]] = struct{}{} + } +} + +// RemoveSpecIDs removes the spec edge to Spec by ids. +func (m *CardMutation) RemoveSpecIDs(ids ...string) { + if m.removedspec == nil { + m.removedspec = make(map[string]struct{}) + } + for i := range ids { + m.removedspec[ids[i]] = struct{}{} + } +} + +// RemovedSpec returns the removed ids of spec. +func (m *CardMutation) RemovedSpecIDs() (ids []string) { + for id := range m.removedspec { + ids = append(ids, id) + } + return +} + +// SpecIDs returns the spec ids in the mutation. +func (m *CardMutation) SpecIDs() (ids []string) { + for id := range m.spec { + ids = append(ids, id) + } + return +} + +// ResetSpec reset all changes of the spec edge. +func (m *CardMutation) ResetSpec() { + m.spec = nil + m.removedspec = nil +} + +// Op returns the operation name. +func (m *CardMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Card). +func (m *CardMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CardMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.create_time != nil { + fields = append(fields, card.FieldCreateTime) + } + if m.update_time != nil { + fields = append(fields, card.FieldUpdateTime) + } + if m.number != nil { + fields = append(fields, card.FieldNumber) + } + if m.name != nil { + fields = append(fields, card.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CardMutation) Field(name string) (ent.Value, bool) { + switch name { + case card.FieldCreateTime: + return m.CreateTime() + case card.FieldUpdateTime: + return m.UpdateTime() + case card.FieldNumber: + return m.Number() + case card.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) SetField(name string, value ent.Value) error { + switch name { + case card.FieldCreateTime: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreateTime(v) + return nil + case card.FieldUpdateTime: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdateTime(v) + return nil + case card.FieldNumber: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNumber(v) + return nil + case card.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CardMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CardMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Card numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CardMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[card.FieldName] { + fields = append(fields, card.FieldName) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CardMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CardMutation) ClearField(name string) error { + switch name { + case card.FieldName: + m.ClearName() + return nil + } + return fmt.Errorf("unknown Card nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CardMutation) ResetField(name string) error { + switch name { + case card.FieldCreateTime: + m.ResetCreateTime() + return nil + case card.FieldUpdateTime: + m.ResetUpdateTime() + return nil + case card.FieldNumber: + m.ResetNumber() + return nil + case card.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CardMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.owner != nil { + edges = append(edges, card.EdgeOwner) + } + if m.spec != nil { + edges = append(edges, card.EdgeSpec) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CardMutation) AddedIDs(name string) []ent.Value { + switch name { + case card.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + case card.EdgeSpec: + ids := make([]ent.Value, 0, len(m.spec)) + for id := range m.spec { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CardMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedspec != nil { + edges = append(edges, card.EdgeSpec) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CardMutation) RemovedIDs(name string) []ent.Value { + switch name { + case card.EdgeSpec: + ids := make([]ent.Value, 0, len(m.removedspec)) + for id := range m.removedspec { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CardMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedowner { + edges = append(edges, card.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CardMutation) EdgeCleared(name string) bool { + switch name { + case card.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CardMutation) ClearEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Card unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CardMutation) ResetEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ResetOwner() + return nil + case card.EdgeSpec: + m.ResetSpec() + return nil + } + return fmt.Errorf("unknown Card edge %s", name) +} + +// CommentMutation represents an operation that mutate the Comments +// nodes in the graph. +type CommentMutation struct { + config + op Op + typ string + id *string + unique_int *int + addunique_int *int + unique_float *float64 + addunique_float *float64 + nillable_int *int + addnillable_int *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*CommentMutation)(nil) + +// newCommentMutation creates new mutation for $n.Name. +func newCommentMutation(c config, op Op) *CommentMutation { + return &CommentMutation{ + config: c, + op: op, + typ: TypeComment, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CommentMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CommentMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CommentMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetUniqueInt sets the unique_int field. +func (m *CommentMutation) SetUniqueInt(i int) { + m.unique_int = &i + m.addunique_int = nil +} + +// UniqueInt returns the unique_int value in the mutation. +func (m *CommentMutation) UniqueInt() (r int, exists bool) { + v := m.unique_int + if v == nil { + return + } + return *v, true +} + +// AddUniqueInt adds i to unique_int. +func (m *CommentMutation) AddUniqueInt(i int) { + if m.addunique_int != nil { + *m.addunique_int += i + } else { + m.addunique_int = &i + } +} + +// AddedUniqueInt returns the value that was added to the unique_int field in this mutation. +func (m *CommentMutation) AddedUniqueInt() (r int, exists bool) { + v := m.addunique_int + if v == nil { + return + } + return *v, true +} + +// ResetUniqueInt reset all changes of the unique_int field. +func (m *CommentMutation) ResetUniqueInt() { + m.unique_int = nil + m.addunique_int = nil +} + +// SetUniqueFloat sets the unique_float field. +func (m *CommentMutation) SetUniqueFloat(f float64) { + m.unique_float = &f + m.addunique_float = nil +} + +// UniqueFloat returns the unique_float value in the mutation. +func (m *CommentMutation) UniqueFloat() (r float64, exists bool) { + v := m.unique_float + if v == nil { + return + } + return *v, true +} + +// AddUniqueFloat adds f to unique_float. +func (m *CommentMutation) AddUniqueFloat(f float64) { + if m.addunique_float != nil { + *m.addunique_float += f + } else { + m.addunique_float = &f + } +} + +// AddedUniqueFloat returns the value that was added to the unique_float field in this mutation. +func (m *CommentMutation) AddedUniqueFloat() (r float64, exists bool) { + v := m.addunique_float + if v == nil { + return + } + return *v, true +} + +// ResetUniqueFloat reset all changes of the unique_float field. +func (m *CommentMutation) ResetUniqueFloat() { + m.unique_float = nil + m.addunique_float = nil +} + +// SetNillableInt sets the nillable_int field. +func (m *CommentMutation) SetNillableInt(i int) { + m.nillable_int = &i + m.addnillable_int = nil +} + +// NillableInt returns the nillable_int value in the mutation. +func (m *CommentMutation) NillableInt() (r int, exists bool) { + v := m.nillable_int + if v == nil { + return + } + return *v, true +} + +// AddNillableInt adds i to nillable_int. +func (m *CommentMutation) AddNillableInt(i int) { + if m.addnillable_int != nil { + *m.addnillable_int += i + } else { + m.addnillable_int = &i + } +} + +// AddedNillableInt returns the value that was added to the nillable_int field in this mutation. +func (m *CommentMutation) AddedNillableInt() (r int, exists bool) { + v := m.addnillable_int + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt clears the value of nillable_int. +func (m *CommentMutation) ClearNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + m.clearedFields[comment.FieldNillableInt] = true +} + +// NillableIntCleared returns if the field nillable_int was cleared in this mutation. +func (m *CommentMutation) NillableIntCleared() bool { + return m.clearedFields[comment.FieldNillableInt] +} + +// ResetNillableInt reset all changes of the nillable_int field. +func (m *CommentMutation) ResetNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + delete(m.clearedFields, comment.FieldNillableInt) +} + +// Op returns the operation name. +func (m *CommentMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Comment). +func (m *CommentMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CommentMutation) Fields() []string { + fields := make([]string, 0, 3) + if m.unique_int != nil { + fields = append(fields, comment.FieldUniqueInt) + } + if m.unique_float != nil { + fields = append(fields, comment.FieldUniqueFloat) + } + if m.nillable_int != nil { + fields = append(fields, comment.FieldNillableInt) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CommentMutation) Field(name string) (ent.Value, bool) { + switch name { + case comment.FieldUniqueInt: + return m.UniqueInt() + case comment.FieldUniqueFloat: + return m.UniqueFloat() + case comment.FieldNillableInt: + return m.NillableInt() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CommentMutation) SetField(name string, value ent.Value) error { + switch name { + case comment.FieldUniqueInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUniqueInt(v) + return nil + case comment.FieldUniqueFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUniqueFloat(v) + return nil + case comment.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt(v) + return nil + } + return fmt.Errorf("unknown Comment field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CommentMutation) AddedFields() []string { + var fields []string + if m.addunique_int != nil { + fields = append(fields, comment.FieldUniqueInt) + } + if m.addunique_float != nil { + fields = append(fields, comment.FieldUniqueFloat) + } + if m.addnillable_int != nil { + fields = append(fields, comment.FieldNillableInt) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CommentMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case comment.FieldUniqueInt: + return m.AddedUniqueInt() + case comment.FieldUniqueFloat: + return m.AddedUniqueFloat() + case comment.FieldNillableInt: + return m.AddedNillableInt() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CommentMutation) AddField(name string, value ent.Value) error { + switch name { + case comment.FieldUniqueInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUniqueInt(v) + return nil + case comment.FieldUniqueFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUniqueFloat(v) + return nil + case comment.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt(v) + return nil + } + return fmt.Errorf("unknown Comment numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CommentMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[comment.FieldNillableInt] { + fields = append(fields, comment.FieldNillableInt) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CommentMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CommentMutation) ClearField(name string) error { + switch name { + case comment.FieldNillableInt: + m.ClearNillableInt() + return nil + } + return fmt.Errorf("unknown Comment nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CommentMutation) ResetField(name string) error { + switch name { + case comment.FieldUniqueInt: + m.ResetUniqueInt() + return nil + case comment.FieldUniqueFloat: + m.ResetUniqueFloat() + return nil + case comment.FieldNillableInt: + m.ResetNillableInt() + return nil + } + return fmt.Errorf("unknown Comment field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CommentMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CommentMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CommentMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CommentMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CommentMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CommentMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CommentMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Comment unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CommentMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Comment edge %s", name) +} + +// FieldTypeMutation represents an operation that mutate the FieldTypes +// nodes in the graph. +type FieldTypeMutation struct { + config + op Op + typ string + id *string + int *int + addint *int + int8 *int8 + addint8 *int8 + int16 *int16 + addint16 *int16 + int32 *int32 + addint32 *int32 + int64 *int64 + addint64 *int64 + optional_int *int + addoptional_int *int + optional_int8 *int8 + addoptional_int8 *int8 + optional_int16 *int16 + addoptional_int16 *int16 + optional_int32 *int32 + addoptional_int32 *int32 + optional_int64 *int64 + addoptional_int64 *int64 + nillable_int *int + addnillable_int *int + nillable_int8 *int8 + addnillable_int8 *int8 + nillable_int16 *int16 + addnillable_int16 *int16 + nillable_int32 *int32 + addnillable_int32 *int32 + nillable_int64 *int64 + addnillable_int64 *int64 + validate_optional_int32 *int32 + addvalidate_optional_int32 *int32 + optional_uint *uint + addoptional_uint *uint + optional_uint8 *uint8 + addoptional_uint8 *uint8 + optional_uint16 *uint16 + addoptional_uint16 *uint16 + optional_uint32 *uint32 + addoptional_uint32 *uint32 + optional_uint64 *uint64 + addoptional_uint64 *uint64 + state *fieldtype.State + optional_float *float64 + addoptional_float *float64 + optional_float32 *float32 + addoptional_float32 *float32 + clearedFields map[string]bool +} + +var _ ent.Mutation = (*FieldTypeMutation)(nil) + +// newFieldTypeMutation creates new mutation for $n.Name. +func newFieldTypeMutation(c config, op Op) *FieldTypeMutation { + return &FieldTypeMutation{ + config: c, + op: op, + typ: TypeFieldType, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m FieldTypeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m FieldTypeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *FieldTypeMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetInt sets the int field. +func (m *FieldTypeMutation) SetInt(i int) { + m.int = &i + m.addint = nil +} + +// Int returns the int value in the mutation. +func (m *FieldTypeMutation) Int() (r int, exists bool) { + v := m.int + if v == nil { + return + } + return *v, true +} + +// AddInt adds i to int. +func (m *FieldTypeMutation) AddInt(i int) { + if m.addint != nil { + *m.addint += i + } else { + m.addint = &i + } +} + +// AddedInt returns the value that was added to the int field in this mutation. +func (m *FieldTypeMutation) AddedInt() (r int, exists bool) { + v := m.addint + if v == nil { + return + } + return *v, true +} + +// ResetInt reset all changes of the int field. +func (m *FieldTypeMutation) ResetInt() { + m.int = nil + m.addint = nil +} + +// SetInt8 sets the int8 field. +func (m *FieldTypeMutation) SetInt8(i int8) { + m.int8 = &i + m.addint8 = nil +} + +// Int8 returns the int8 value in the mutation. +func (m *FieldTypeMutation) Int8() (r int8, exists bool) { + v := m.int8 + if v == nil { + return + } + return *v, true +} + +// AddInt8 adds i to int8. +func (m *FieldTypeMutation) AddInt8(i int8) { + if m.addint8 != nil { + *m.addint8 += i + } else { + m.addint8 = &i + } +} + +// AddedInt8 returns the value that was added to the int8 field in this mutation. +func (m *FieldTypeMutation) AddedInt8() (r int8, exists bool) { + v := m.addint8 + if v == nil { + return + } + return *v, true +} + +// ResetInt8 reset all changes of the int8 field. +func (m *FieldTypeMutation) ResetInt8() { + m.int8 = nil + m.addint8 = nil +} + +// SetInt16 sets the int16 field. +func (m *FieldTypeMutation) SetInt16(i int16) { + m.int16 = &i + m.addint16 = nil +} + +// Int16 returns the int16 value in the mutation. +func (m *FieldTypeMutation) Int16() (r int16, exists bool) { + v := m.int16 + if v == nil { + return + } + return *v, true +} + +// AddInt16 adds i to int16. +func (m *FieldTypeMutation) AddInt16(i int16) { + if m.addint16 != nil { + *m.addint16 += i + } else { + m.addint16 = &i + } +} + +// AddedInt16 returns the value that was added to the int16 field in this mutation. +func (m *FieldTypeMutation) AddedInt16() (r int16, exists bool) { + v := m.addint16 + if v == nil { + return + } + return *v, true +} + +// ResetInt16 reset all changes of the int16 field. +func (m *FieldTypeMutation) ResetInt16() { + m.int16 = nil + m.addint16 = nil +} + +// SetInt32 sets the int32 field. +func (m *FieldTypeMutation) SetInt32(i int32) { + m.int32 = &i + m.addint32 = nil +} + +// Int32 returns the int32 value in the mutation. +func (m *FieldTypeMutation) Int32() (r int32, exists bool) { + v := m.int32 + if v == nil { + return + } + return *v, true +} + +// AddInt32 adds i to int32. +func (m *FieldTypeMutation) AddInt32(i int32) { + if m.addint32 != nil { + *m.addint32 += i + } else { + m.addint32 = &i + } +} + +// AddedInt32 returns the value that was added to the int32 field in this mutation. +func (m *FieldTypeMutation) AddedInt32() (r int32, exists bool) { + v := m.addint32 + if v == nil { + return + } + return *v, true +} + +// ResetInt32 reset all changes of the int32 field. +func (m *FieldTypeMutation) ResetInt32() { + m.int32 = nil + m.addint32 = nil +} + +// SetInt64 sets the int64 field. +func (m *FieldTypeMutation) SetInt64(i int64) { + m.int64 = &i + m.addint64 = nil +} + +// Int64 returns the int64 value in the mutation. +func (m *FieldTypeMutation) Int64() (r int64, exists bool) { + v := m.int64 + if v == nil { + return + } + return *v, true +} + +// AddInt64 adds i to int64. +func (m *FieldTypeMutation) AddInt64(i int64) { + if m.addint64 != nil { + *m.addint64 += i + } else { + m.addint64 = &i + } +} + +// AddedInt64 returns the value that was added to the int64 field in this mutation. +func (m *FieldTypeMutation) AddedInt64() (r int64, exists bool) { + v := m.addint64 + if v == nil { + return + } + return *v, true +} + +// ResetInt64 reset all changes of the int64 field. +func (m *FieldTypeMutation) ResetInt64() { + m.int64 = nil + m.addint64 = nil +} + +// SetOptionalInt sets the optional_int field. +func (m *FieldTypeMutation) SetOptionalInt(i int) { + m.optional_int = &i + m.addoptional_int = nil +} + +// OptionalInt returns the optional_int value in the mutation. +func (m *FieldTypeMutation) OptionalInt() (r int, exists bool) { + v := m.optional_int + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt adds i to optional_int. +func (m *FieldTypeMutation) AddOptionalInt(i int) { + if m.addoptional_int != nil { + *m.addoptional_int += i + } else { + m.addoptional_int = &i + } +} + +// AddedOptionalInt returns the value that was added to the optional_int field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt() (r int, exists bool) { + v := m.addoptional_int + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt clears the value of optional_int. +func (m *FieldTypeMutation) ClearOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + m.clearedFields[fieldtype.FieldOptionalInt] = true +} + +// OptionalIntCleared returns if the field optional_int was cleared in this mutation. +func (m *FieldTypeMutation) OptionalIntCleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt] +} + +// ResetOptionalInt reset all changes of the optional_int field. +func (m *FieldTypeMutation) ResetOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt) +} + +// SetOptionalInt8 sets the optional_int8 field. +func (m *FieldTypeMutation) SetOptionalInt8(i int8) { + m.optional_int8 = &i + m.addoptional_int8 = nil +} + +// OptionalInt8 returns the optional_int8 value in the mutation. +func (m *FieldTypeMutation) OptionalInt8() (r int8, exists bool) { + v := m.optional_int8 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt8 adds i to optional_int8. +func (m *FieldTypeMutation) AddOptionalInt8(i int8) { + if m.addoptional_int8 != nil { + *m.addoptional_int8 += i + } else { + m.addoptional_int8 = &i + } +} + +// AddedOptionalInt8 returns the value that was added to the optional_int8 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt8() (r int8, exists bool) { + v := m.addoptional_int8 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt8 clears the value of optional_int8. +func (m *FieldTypeMutation) ClearOptionalInt8() { + m.optional_int8 = nil + m.addoptional_int8 = nil + m.clearedFields[fieldtype.FieldOptionalInt8] = true +} + +// OptionalInt8Cleared returns if the field optional_int8 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt8Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt8] +} + +// ResetOptionalInt8 reset all changes of the optional_int8 field. +func (m *FieldTypeMutation) ResetOptionalInt8() { + m.optional_int8 = nil + m.addoptional_int8 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt8) +} + +// SetOptionalInt16 sets the optional_int16 field. +func (m *FieldTypeMutation) SetOptionalInt16(i int16) { + m.optional_int16 = &i + m.addoptional_int16 = nil +} + +// OptionalInt16 returns the optional_int16 value in the mutation. +func (m *FieldTypeMutation) OptionalInt16() (r int16, exists bool) { + v := m.optional_int16 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt16 adds i to optional_int16. +func (m *FieldTypeMutation) AddOptionalInt16(i int16) { + if m.addoptional_int16 != nil { + *m.addoptional_int16 += i + } else { + m.addoptional_int16 = &i + } +} + +// AddedOptionalInt16 returns the value that was added to the optional_int16 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt16() (r int16, exists bool) { + v := m.addoptional_int16 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt16 clears the value of optional_int16. +func (m *FieldTypeMutation) ClearOptionalInt16() { + m.optional_int16 = nil + m.addoptional_int16 = nil + m.clearedFields[fieldtype.FieldOptionalInt16] = true +} + +// OptionalInt16Cleared returns if the field optional_int16 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt16Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt16] +} + +// ResetOptionalInt16 reset all changes of the optional_int16 field. +func (m *FieldTypeMutation) ResetOptionalInt16() { + m.optional_int16 = nil + m.addoptional_int16 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt16) +} + +// SetOptionalInt32 sets the optional_int32 field. +func (m *FieldTypeMutation) SetOptionalInt32(i int32) { + m.optional_int32 = &i + m.addoptional_int32 = nil +} + +// OptionalInt32 returns the optional_int32 value in the mutation. +func (m *FieldTypeMutation) OptionalInt32() (r int32, exists bool) { + v := m.optional_int32 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt32 adds i to optional_int32. +func (m *FieldTypeMutation) AddOptionalInt32(i int32) { + if m.addoptional_int32 != nil { + *m.addoptional_int32 += i + } else { + m.addoptional_int32 = &i + } +} + +// AddedOptionalInt32 returns the value that was added to the optional_int32 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt32() (r int32, exists bool) { + v := m.addoptional_int32 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt32 clears the value of optional_int32. +func (m *FieldTypeMutation) ClearOptionalInt32() { + m.optional_int32 = nil + m.addoptional_int32 = nil + m.clearedFields[fieldtype.FieldOptionalInt32] = true +} + +// OptionalInt32Cleared returns if the field optional_int32 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt32Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt32] +} + +// ResetOptionalInt32 reset all changes of the optional_int32 field. +func (m *FieldTypeMutation) ResetOptionalInt32() { + m.optional_int32 = nil + m.addoptional_int32 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt32) +} + +// SetOptionalInt64 sets the optional_int64 field. +func (m *FieldTypeMutation) SetOptionalInt64(i int64) { + m.optional_int64 = &i + m.addoptional_int64 = nil +} + +// OptionalInt64 returns the optional_int64 value in the mutation. +func (m *FieldTypeMutation) OptionalInt64() (r int64, exists bool) { + v := m.optional_int64 + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt64 adds i to optional_int64. +func (m *FieldTypeMutation) AddOptionalInt64(i int64) { + if m.addoptional_int64 != nil { + *m.addoptional_int64 += i + } else { + m.addoptional_int64 = &i + } +} + +// AddedOptionalInt64 returns the value that was added to the optional_int64 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalInt64() (r int64, exists bool) { + v := m.addoptional_int64 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt64 clears the value of optional_int64. +func (m *FieldTypeMutation) ClearOptionalInt64() { + m.optional_int64 = nil + m.addoptional_int64 = nil + m.clearedFields[fieldtype.FieldOptionalInt64] = true +} + +// OptionalInt64Cleared returns if the field optional_int64 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalInt64Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalInt64] +} + +// ResetOptionalInt64 reset all changes of the optional_int64 field. +func (m *FieldTypeMutation) ResetOptionalInt64() { + m.optional_int64 = nil + m.addoptional_int64 = nil + delete(m.clearedFields, fieldtype.FieldOptionalInt64) +} + +// SetNillableInt sets the nillable_int field. +func (m *FieldTypeMutation) SetNillableInt(i int) { + m.nillable_int = &i + m.addnillable_int = nil +} + +// NillableInt returns the nillable_int value in the mutation. +func (m *FieldTypeMutation) NillableInt() (r int, exists bool) { + v := m.nillable_int + if v == nil { + return + } + return *v, true +} + +// AddNillableInt adds i to nillable_int. +func (m *FieldTypeMutation) AddNillableInt(i int) { + if m.addnillable_int != nil { + *m.addnillable_int += i + } else { + m.addnillable_int = &i + } +} + +// AddedNillableInt returns the value that was added to the nillable_int field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt() (r int, exists bool) { + v := m.addnillable_int + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt clears the value of nillable_int. +func (m *FieldTypeMutation) ClearNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + m.clearedFields[fieldtype.FieldNillableInt] = true +} + +// NillableIntCleared returns if the field nillable_int was cleared in this mutation. +func (m *FieldTypeMutation) NillableIntCleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt] +} + +// ResetNillableInt reset all changes of the nillable_int field. +func (m *FieldTypeMutation) ResetNillableInt() { + m.nillable_int = nil + m.addnillable_int = nil + delete(m.clearedFields, fieldtype.FieldNillableInt) +} + +// SetNillableInt8 sets the nillable_int8 field. +func (m *FieldTypeMutation) SetNillableInt8(i int8) { + m.nillable_int8 = &i + m.addnillable_int8 = nil +} + +// NillableInt8 returns the nillable_int8 value in the mutation. +func (m *FieldTypeMutation) NillableInt8() (r int8, exists bool) { + v := m.nillable_int8 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt8 adds i to nillable_int8. +func (m *FieldTypeMutation) AddNillableInt8(i int8) { + if m.addnillable_int8 != nil { + *m.addnillable_int8 += i + } else { + m.addnillable_int8 = &i + } +} + +// AddedNillableInt8 returns the value that was added to the nillable_int8 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt8() (r int8, exists bool) { + v := m.addnillable_int8 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt8 clears the value of nillable_int8. +func (m *FieldTypeMutation) ClearNillableInt8() { + m.nillable_int8 = nil + m.addnillable_int8 = nil + m.clearedFields[fieldtype.FieldNillableInt8] = true +} + +// NillableInt8Cleared returns if the field nillable_int8 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt8Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt8] +} + +// ResetNillableInt8 reset all changes of the nillable_int8 field. +func (m *FieldTypeMutation) ResetNillableInt8() { + m.nillable_int8 = nil + m.addnillable_int8 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt8) +} + +// SetNillableInt16 sets the nillable_int16 field. +func (m *FieldTypeMutation) SetNillableInt16(i int16) { + m.nillable_int16 = &i + m.addnillable_int16 = nil +} + +// NillableInt16 returns the nillable_int16 value in the mutation. +func (m *FieldTypeMutation) NillableInt16() (r int16, exists bool) { + v := m.nillable_int16 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt16 adds i to nillable_int16. +func (m *FieldTypeMutation) AddNillableInt16(i int16) { + if m.addnillable_int16 != nil { + *m.addnillable_int16 += i + } else { + m.addnillable_int16 = &i + } +} + +// AddedNillableInt16 returns the value that was added to the nillable_int16 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt16() (r int16, exists bool) { + v := m.addnillable_int16 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt16 clears the value of nillable_int16. +func (m *FieldTypeMutation) ClearNillableInt16() { + m.nillable_int16 = nil + m.addnillable_int16 = nil + m.clearedFields[fieldtype.FieldNillableInt16] = true +} + +// NillableInt16Cleared returns if the field nillable_int16 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt16Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt16] +} + +// ResetNillableInt16 reset all changes of the nillable_int16 field. +func (m *FieldTypeMutation) ResetNillableInt16() { + m.nillable_int16 = nil + m.addnillable_int16 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt16) +} + +// SetNillableInt32 sets the nillable_int32 field. +func (m *FieldTypeMutation) SetNillableInt32(i int32) { + m.nillable_int32 = &i + m.addnillable_int32 = nil +} + +// NillableInt32 returns the nillable_int32 value in the mutation. +func (m *FieldTypeMutation) NillableInt32() (r int32, exists bool) { + v := m.nillable_int32 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt32 adds i to nillable_int32. +func (m *FieldTypeMutation) AddNillableInt32(i int32) { + if m.addnillable_int32 != nil { + *m.addnillable_int32 += i + } else { + m.addnillable_int32 = &i + } +} + +// AddedNillableInt32 returns the value that was added to the nillable_int32 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt32() (r int32, exists bool) { + v := m.addnillable_int32 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt32 clears the value of nillable_int32. +func (m *FieldTypeMutation) ClearNillableInt32() { + m.nillable_int32 = nil + m.addnillable_int32 = nil + m.clearedFields[fieldtype.FieldNillableInt32] = true +} + +// NillableInt32Cleared returns if the field nillable_int32 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt32Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt32] +} + +// ResetNillableInt32 reset all changes of the nillable_int32 field. +func (m *FieldTypeMutation) ResetNillableInt32() { + m.nillable_int32 = nil + m.addnillable_int32 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt32) +} + +// SetNillableInt64 sets the nillable_int64 field. +func (m *FieldTypeMutation) SetNillableInt64(i int64) { + m.nillable_int64 = &i + m.addnillable_int64 = nil +} + +// NillableInt64 returns the nillable_int64 value in the mutation. +func (m *FieldTypeMutation) NillableInt64() (r int64, exists bool) { + v := m.nillable_int64 + if v == nil { + return + } + return *v, true +} + +// AddNillableInt64 adds i to nillable_int64. +func (m *FieldTypeMutation) AddNillableInt64(i int64) { + if m.addnillable_int64 != nil { + *m.addnillable_int64 += i + } else { + m.addnillable_int64 = &i + } +} + +// AddedNillableInt64 returns the value that was added to the nillable_int64 field in this mutation. +func (m *FieldTypeMutation) AddedNillableInt64() (r int64, exists bool) { + v := m.addnillable_int64 + if v == nil { + return + } + return *v, true +} + +// ClearNillableInt64 clears the value of nillable_int64. +func (m *FieldTypeMutation) ClearNillableInt64() { + m.nillable_int64 = nil + m.addnillable_int64 = nil + m.clearedFields[fieldtype.FieldNillableInt64] = true +} + +// NillableInt64Cleared returns if the field nillable_int64 was cleared in this mutation. +func (m *FieldTypeMutation) NillableInt64Cleared() bool { + return m.clearedFields[fieldtype.FieldNillableInt64] +} + +// ResetNillableInt64 reset all changes of the nillable_int64 field. +func (m *FieldTypeMutation) ResetNillableInt64() { + m.nillable_int64 = nil + m.addnillable_int64 = nil + delete(m.clearedFields, fieldtype.FieldNillableInt64) +} + +// SetValidateOptionalInt32 sets the validate_optional_int32 field. +func (m *FieldTypeMutation) SetValidateOptionalInt32(i int32) { + m.validate_optional_int32 = &i + m.addvalidate_optional_int32 = nil +} + +// ValidateOptionalInt32 returns the validate_optional_int32 value in the mutation. +func (m *FieldTypeMutation) ValidateOptionalInt32() (r int32, exists bool) { + v := m.validate_optional_int32 + if v == nil { + return + } + return *v, true +} + +// AddValidateOptionalInt32 adds i to validate_optional_int32. +func (m *FieldTypeMutation) AddValidateOptionalInt32(i int32) { + if m.addvalidate_optional_int32 != nil { + *m.addvalidate_optional_int32 += i + } else { + m.addvalidate_optional_int32 = &i + } +} + +// AddedValidateOptionalInt32 returns the value that was added to the validate_optional_int32 field in this mutation. +func (m *FieldTypeMutation) AddedValidateOptionalInt32() (r int32, exists bool) { + v := m.addvalidate_optional_int32 + if v == nil { + return + } + return *v, true +} + +// ClearValidateOptionalInt32 clears the value of validate_optional_int32. +func (m *FieldTypeMutation) ClearValidateOptionalInt32() { + m.validate_optional_int32 = nil + m.addvalidate_optional_int32 = nil + m.clearedFields[fieldtype.FieldValidateOptionalInt32] = true +} + +// ValidateOptionalInt32Cleared returns if the field validate_optional_int32 was cleared in this mutation. +func (m *FieldTypeMutation) ValidateOptionalInt32Cleared() bool { + return m.clearedFields[fieldtype.FieldValidateOptionalInt32] +} + +// ResetValidateOptionalInt32 reset all changes of the validate_optional_int32 field. +func (m *FieldTypeMutation) ResetValidateOptionalInt32() { + m.validate_optional_int32 = nil + m.addvalidate_optional_int32 = nil + delete(m.clearedFields, fieldtype.FieldValidateOptionalInt32) +} + +// SetOptionalUint sets the optional_uint field. +func (m *FieldTypeMutation) SetOptionalUint(u uint) { + m.optional_uint = &u + m.addoptional_uint = nil +} + +// OptionalUint returns the optional_uint value in the mutation. +func (m *FieldTypeMutation) OptionalUint() (r uint, exists bool) { + v := m.optional_uint + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint adds u to optional_uint. +func (m *FieldTypeMutation) AddOptionalUint(u uint) { + if m.addoptional_uint != nil { + *m.addoptional_uint += u + } else { + m.addoptional_uint = &u + } +} + +// AddedOptionalUint returns the value that was added to the optional_uint field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint() (r uint, exists bool) { + v := m.addoptional_uint + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint clears the value of optional_uint. +func (m *FieldTypeMutation) ClearOptionalUint() { + m.optional_uint = nil + m.addoptional_uint = nil + m.clearedFields[fieldtype.FieldOptionalUint] = true +} + +// OptionalUintCleared returns if the field optional_uint was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUintCleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint] +} + +// ResetOptionalUint reset all changes of the optional_uint field. +func (m *FieldTypeMutation) ResetOptionalUint() { + m.optional_uint = nil + m.addoptional_uint = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint) +} + +// SetOptionalUint8 sets the optional_uint8 field. +func (m *FieldTypeMutation) SetOptionalUint8(u uint8) { + m.optional_uint8 = &u + m.addoptional_uint8 = nil +} + +// OptionalUint8 returns the optional_uint8 value in the mutation. +func (m *FieldTypeMutation) OptionalUint8() (r uint8, exists bool) { + v := m.optional_uint8 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint8 adds u to optional_uint8. +func (m *FieldTypeMutation) AddOptionalUint8(u uint8) { + if m.addoptional_uint8 != nil { + *m.addoptional_uint8 += u + } else { + m.addoptional_uint8 = &u + } +} + +// AddedOptionalUint8 returns the value that was added to the optional_uint8 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint8() (r uint8, exists bool) { + v := m.addoptional_uint8 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint8 clears the value of optional_uint8. +func (m *FieldTypeMutation) ClearOptionalUint8() { + m.optional_uint8 = nil + m.addoptional_uint8 = nil + m.clearedFields[fieldtype.FieldOptionalUint8] = true +} + +// OptionalUint8Cleared returns if the field optional_uint8 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint8Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint8] +} + +// ResetOptionalUint8 reset all changes of the optional_uint8 field. +func (m *FieldTypeMutation) ResetOptionalUint8() { + m.optional_uint8 = nil + m.addoptional_uint8 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint8) +} + +// SetOptionalUint16 sets the optional_uint16 field. +func (m *FieldTypeMutation) SetOptionalUint16(u uint16) { + m.optional_uint16 = &u + m.addoptional_uint16 = nil +} + +// OptionalUint16 returns the optional_uint16 value in the mutation. +func (m *FieldTypeMutation) OptionalUint16() (r uint16, exists bool) { + v := m.optional_uint16 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint16 adds u to optional_uint16. +func (m *FieldTypeMutation) AddOptionalUint16(u uint16) { + if m.addoptional_uint16 != nil { + *m.addoptional_uint16 += u + } else { + m.addoptional_uint16 = &u + } +} + +// AddedOptionalUint16 returns the value that was added to the optional_uint16 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint16() (r uint16, exists bool) { + v := m.addoptional_uint16 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint16 clears the value of optional_uint16. +func (m *FieldTypeMutation) ClearOptionalUint16() { + m.optional_uint16 = nil + m.addoptional_uint16 = nil + m.clearedFields[fieldtype.FieldOptionalUint16] = true +} + +// OptionalUint16Cleared returns if the field optional_uint16 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint16Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint16] +} + +// ResetOptionalUint16 reset all changes of the optional_uint16 field. +func (m *FieldTypeMutation) ResetOptionalUint16() { + m.optional_uint16 = nil + m.addoptional_uint16 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint16) +} + +// SetOptionalUint32 sets the optional_uint32 field. +func (m *FieldTypeMutation) SetOptionalUint32(u uint32) { + m.optional_uint32 = &u + m.addoptional_uint32 = nil +} + +// OptionalUint32 returns the optional_uint32 value in the mutation. +func (m *FieldTypeMutation) OptionalUint32() (r uint32, exists bool) { + v := m.optional_uint32 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint32 adds u to optional_uint32. +func (m *FieldTypeMutation) AddOptionalUint32(u uint32) { + if m.addoptional_uint32 != nil { + *m.addoptional_uint32 += u + } else { + m.addoptional_uint32 = &u + } +} + +// AddedOptionalUint32 returns the value that was added to the optional_uint32 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint32() (r uint32, exists bool) { + v := m.addoptional_uint32 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint32 clears the value of optional_uint32. +func (m *FieldTypeMutation) ClearOptionalUint32() { + m.optional_uint32 = nil + m.addoptional_uint32 = nil + m.clearedFields[fieldtype.FieldOptionalUint32] = true +} + +// OptionalUint32Cleared returns if the field optional_uint32 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint32Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint32] +} + +// ResetOptionalUint32 reset all changes of the optional_uint32 field. +func (m *FieldTypeMutation) ResetOptionalUint32() { + m.optional_uint32 = nil + m.addoptional_uint32 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint32) +} + +// SetOptionalUint64 sets the optional_uint64 field. +func (m *FieldTypeMutation) SetOptionalUint64(u uint64) { + m.optional_uint64 = &u + m.addoptional_uint64 = nil +} + +// OptionalUint64 returns the optional_uint64 value in the mutation. +func (m *FieldTypeMutation) OptionalUint64() (r uint64, exists bool) { + v := m.optional_uint64 + if v == nil { + return + } + return *v, true +} + +// AddOptionalUint64 adds u to optional_uint64. +func (m *FieldTypeMutation) AddOptionalUint64(u uint64) { + if m.addoptional_uint64 != nil { + *m.addoptional_uint64 += u + } else { + m.addoptional_uint64 = &u + } +} + +// AddedOptionalUint64 returns the value that was added to the optional_uint64 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalUint64() (r uint64, exists bool) { + v := m.addoptional_uint64 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalUint64 clears the value of optional_uint64. +func (m *FieldTypeMutation) ClearOptionalUint64() { + m.optional_uint64 = nil + m.addoptional_uint64 = nil + m.clearedFields[fieldtype.FieldOptionalUint64] = true +} + +// OptionalUint64Cleared returns if the field optional_uint64 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalUint64Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalUint64] +} + +// ResetOptionalUint64 reset all changes of the optional_uint64 field. +func (m *FieldTypeMutation) ResetOptionalUint64() { + m.optional_uint64 = nil + m.addoptional_uint64 = nil + delete(m.clearedFields, fieldtype.FieldOptionalUint64) +} + +// SetState sets the state field. +func (m *FieldTypeMutation) SetState(f fieldtype.State) { + m.state = &f +} + +// State returns the state value in the mutation. +func (m *FieldTypeMutation) State() (r fieldtype.State, exists bool) { + v := m.state + if v == nil { + return + } + return *v, true +} + +// ClearState clears the value of state. +func (m *FieldTypeMutation) ClearState() { + m.state = nil + m.clearedFields[fieldtype.FieldState] = true +} + +// StateCleared returns if the field state was cleared in this mutation. +func (m *FieldTypeMutation) StateCleared() bool { + return m.clearedFields[fieldtype.FieldState] +} + +// ResetState reset all changes of the state field. +func (m *FieldTypeMutation) ResetState() { + m.state = nil + delete(m.clearedFields, fieldtype.FieldState) +} + +// SetOptionalFloat sets the optional_float field. +func (m *FieldTypeMutation) SetOptionalFloat(f float64) { + m.optional_float = &f + m.addoptional_float = nil +} + +// OptionalFloat returns the optional_float value in the mutation. +func (m *FieldTypeMutation) OptionalFloat() (r float64, exists bool) { + v := m.optional_float + if v == nil { + return + } + return *v, true +} + +// AddOptionalFloat adds f to optional_float. +func (m *FieldTypeMutation) AddOptionalFloat(f float64) { + if m.addoptional_float != nil { + *m.addoptional_float += f + } else { + m.addoptional_float = &f + } +} + +// AddedOptionalFloat returns the value that was added to the optional_float field in this mutation. +func (m *FieldTypeMutation) AddedOptionalFloat() (r float64, exists bool) { + v := m.addoptional_float + if v == nil { + return + } + return *v, true +} + +// ClearOptionalFloat clears the value of optional_float. +func (m *FieldTypeMutation) ClearOptionalFloat() { + m.optional_float = nil + m.addoptional_float = nil + m.clearedFields[fieldtype.FieldOptionalFloat] = true +} + +// OptionalFloatCleared returns if the field optional_float was cleared in this mutation. +func (m *FieldTypeMutation) OptionalFloatCleared() bool { + return m.clearedFields[fieldtype.FieldOptionalFloat] +} + +// ResetOptionalFloat reset all changes of the optional_float field. +func (m *FieldTypeMutation) ResetOptionalFloat() { + m.optional_float = nil + m.addoptional_float = nil + delete(m.clearedFields, fieldtype.FieldOptionalFloat) +} + +// SetOptionalFloat32 sets the optional_float32 field. +func (m *FieldTypeMutation) SetOptionalFloat32(f float32) { + m.optional_float32 = &f + m.addoptional_float32 = nil +} + +// OptionalFloat32 returns the optional_float32 value in the mutation. +func (m *FieldTypeMutation) OptionalFloat32() (r float32, exists bool) { + v := m.optional_float32 + if v == nil { + return + } + return *v, true +} + +// AddOptionalFloat32 adds f to optional_float32. +func (m *FieldTypeMutation) AddOptionalFloat32(f float32) { + if m.addoptional_float32 != nil { + *m.addoptional_float32 += f + } else { + m.addoptional_float32 = &f + } +} + +// AddedOptionalFloat32 returns the value that was added to the optional_float32 field in this mutation. +func (m *FieldTypeMutation) AddedOptionalFloat32() (r float32, exists bool) { + v := m.addoptional_float32 + if v == nil { + return + } + return *v, true +} + +// ClearOptionalFloat32 clears the value of optional_float32. +func (m *FieldTypeMutation) ClearOptionalFloat32() { + m.optional_float32 = nil + m.addoptional_float32 = nil + m.clearedFields[fieldtype.FieldOptionalFloat32] = true +} + +// OptionalFloat32Cleared returns if the field optional_float32 was cleared in this mutation. +func (m *FieldTypeMutation) OptionalFloat32Cleared() bool { + return m.clearedFields[fieldtype.FieldOptionalFloat32] +} + +// ResetOptionalFloat32 reset all changes of the optional_float32 field. +func (m *FieldTypeMutation) ResetOptionalFloat32() { + m.optional_float32 = nil + m.addoptional_float32 = nil + delete(m.clearedFields, fieldtype.FieldOptionalFloat32) +} + +// Op returns the operation name. +func (m *FieldTypeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (FieldType). +func (m *FieldTypeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *FieldTypeMutation) Fields() []string { + fields := make([]string, 0, 24) + if m.int != nil { + fields = append(fields, fieldtype.FieldInt) + } + if m.int8 != nil { + fields = append(fields, fieldtype.FieldInt8) + } + if m.int16 != nil { + fields = append(fields, fieldtype.FieldInt16) + } + if m.int32 != nil { + fields = append(fields, fieldtype.FieldInt32) + } + if m.int64 != nil { + fields = append(fields, fieldtype.FieldInt64) + } + if m.optional_int != nil { + fields = append(fields, fieldtype.FieldOptionalInt) + } + if m.optional_int8 != nil { + fields = append(fields, fieldtype.FieldOptionalInt8) + } + if m.optional_int16 != nil { + fields = append(fields, fieldtype.FieldOptionalInt16) + } + if m.optional_int32 != nil { + fields = append(fields, fieldtype.FieldOptionalInt32) + } + if m.optional_int64 != nil { + fields = append(fields, fieldtype.FieldOptionalInt64) + } + if m.nillable_int != nil { + fields = append(fields, fieldtype.FieldNillableInt) + } + if m.nillable_int8 != nil { + fields = append(fields, fieldtype.FieldNillableInt8) + } + if m.nillable_int16 != nil { + fields = append(fields, fieldtype.FieldNillableInt16) + } + if m.nillable_int32 != nil { + fields = append(fields, fieldtype.FieldNillableInt32) + } + if m.nillable_int64 != nil { + fields = append(fields, fieldtype.FieldNillableInt64) + } + if m.validate_optional_int32 != nil { + fields = append(fields, fieldtype.FieldValidateOptionalInt32) + } + if m.optional_uint != nil { + fields = append(fields, fieldtype.FieldOptionalUint) + } + if m.optional_uint8 != nil { + fields = append(fields, fieldtype.FieldOptionalUint8) + } + if m.optional_uint16 != nil { + fields = append(fields, fieldtype.FieldOptionalUint16) + } + if m.optional_uint32 != nil { + fields = append(fields, fieldtype.FieldOptionalUint32) + } + if m.optional_uint64 != nil { + fields = append(fields, fieldtype.FieldOptionalUint64) + } + if m.state != nil { + fields = append(fields, fieldtype.FieldState) + } + if m.optional_float != nil { + fields = append(fields, fieldtype.FieldOptionalFloat) + } + if m.optional_float32 != nil { + fields = append(fields, fieldtype.FieldOptionalFloat32) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *FieldTypeMutation) Field(name string) (ent.Value, bool) { + switch name { + case fieldtype.FieldInt: + return m.Int() + case fieldtype.FieldInt8: + return m.Int8() + case fieldtype.FieldInt16: + return m.Int16() + case fieldtype.FieldInt32: + return m.Int32() + case fieldtype.FieldInt64: + return m.Int64() + case fieldtype.FieldOptionalInt: + return m.OptionalInt() + case fieldtype.FieldOptionalInt8: + return m.OptionalInt8() + case fieldtype.FieldOptionalInt16: + return m.OptionalInt16() + case fieldtype.FieldOptionalInt32: + return m.OptionalInt32() + case fieldtype.FieldOptionalInt64: + return m.OptionalInt64() + case fieldtype.FieldNillableInt: + return m.NillableInt() + case fieldtype.FieldNillableInt8: + return m.NillableInt8() + case fieldtype.FieldNillableInt16: + return m.NillableInt16() + case fieldtype.FieldNillableInt32: + return m.NillableInt32() + case fieldtype.FieldNillableInt64: + return m.NillableInt64() + case fieldtype.FieldValidateOptionalInt32: + return m.ValidateOptionalInt32() + case fieldtype.FieldOptionalUint: + return m.OptionalUint() + case fieldtype.FieldOptionalUint8: + return m.OptionalUint8() + case fieldtype.FieldOptionalUint16: + return m.OptionalUint16() + case fieldtype.FieldOptionalUint32: + return m.OptionalUint32() + case fieldtype.FieldOptionalUint64: + return m.OptionalUint64() + case fieldtype.FieldState: + return m.State() + case fieldtype.FieldOptionalFloat: + return m.OptionalFloat() + case fieldtype.FieldOptionalFloat32: + return m.OptionalFloat32() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FieldTypeMutation) SetField(name string, value ent.Value) error { + switch name { + case fieldtype.FieldInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt(v) + return nil + case fieldtype.FieldInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt8(v) + return nil + case fieldtype.FieldInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt16(v) + return nil + case fieldtype.FieldInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt32(v) + return nil + case fieldtype.FieldInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInt64(v) + return nil + case fieldtype.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt(v) + return nil + case fieldtype.FieldOptionalInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt8(v) + return nil + case fieldtype.FieldOptionalInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt16(v) + return nil + case fieldtype.FieldOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt32(v) + return nil + case fieldtype.FieldOptionalInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt64(v) + return nil + case fieldtype.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt(v) + return nil + case fieldtype.FieldNillableInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt8(v) + return nil + case fieldtype.FieldNillableInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt16(v) + return nil + case fieldtype.FieldNillableInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt32(v) + return nil + case fieldtype.FieldNillableInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNillableInt64(v) + return nil + case fieldtype.FieldValidateOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValidateOptionalInt32(v) + return nil + case fieldtype.FieldOptionalUint: + v, ok := value.(uint) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint(v) + return nil + case fieldtype.FieldOptionalUint8: + v, ok := value.(uint8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint8(v) + return nil + case fieldtype.FieldOptionalUint16: + v, ok := value.(uint16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint16(v) + return nil + case fieldtype.FieldOptionalUint32: + v, ok := value.(uint32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint32(v) + return nil + case fieldtype.FieldOptionalUint64: + v, ok := value.(uint64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalUint64(v) + return nil + case fieldtype.FieldState: + v, ok := value.(fieldtype.State) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetState(v) + return nil + case fieldtype.FieldOptionalFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalFloat(v) + return nil + case fieldtype.FieldOptionalFloat32: + v, ok := value.(float32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalFloat32(v) + return nil + } + return fmt.Errorf("unknown FieldType field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *FieldTypeMutation) AddedFields() []string { + var fields []string + if m.addint != nil { + fields = append(fields, fieldtype.FieldInt) + } + if m.addint8 != nil { + fields = append(fields, fieldtype.FieldInt8) + } + if m.addint16 != nil { + fields = append(fields, fieldtype.FieldInt16) + } + if m.addint32 != nil { + fields = append(fields, fieldtype.FieldInt32) + } + if m.addint64 != nil { + fields = append(fields, fieldtype.FieldInt64) + } + if m.addoptional_int != nil { + fields = append(fields, fieldtype.FieldOptionalInt) + } + if m.addoptional_int8 != nil { + fields = append(fields, fieldtype.FieldOptionalInt8) + } + if m.addoptional_int16 != nil { + fields = append(fields, fieldtype.FieldOptionalInt16) + } + if m.addoptional_int32 != nil { + fields = append(fields, fieldtype.FieldOptionalInt32) + } + if m.addoptional_int64 != nil { + fields = append(fields, fieldtype.FieldOptionalInt64) + } + if m.addnillable_int != nil { + fields = append(fields, fieldtype.FieldNillableInt) + } + if m.addnillable_int8 != nil { + fields = append(fields, fieldtype.FieldNillableInt8) + } + if m.addnillable_int16 != nil { + fields = append(fields, fieldtype.FieldNillableInt16) + } + if m.addnillable_int32 != nil { + fields = append(fields, fieldtype.FieldNillableInt32) + } + if m.addnillable_int64 != nil { + fields = append(fields, fieldtype.FieldNillableInt64) + } + if m.addvalidate_optional_int32 != nil { + fields = append(fields, fieldtype.FieldValidateOptionalInt32) + } + if m.addoptional_uint != nil { + fields = append(fields, fieldtype.FieldOptionalUint) + } + if m.addoptional_uint8 != nil { + fields = append(fields, fieldtype.FieldOptionalUint8) + } + if m.addoptional_uint16 != nil { + fields = append(fields, fieldtype.FieldOptionalUint16) + } + if m.addoptional_uint32 != nil { + fields = append(fields, fieldtype.FieldOptionalUint32) + } + if m.addoptional_uint64 != nil { + fields = append(fields, fieldtype.FieldOptionalUint64) + } + if m.addoptional_float != nil { + fields = append(fields, fieldtype.FieldOptionalFloat) + } + if m.addoptional_float32 != nil { + fields = append(fields, fieldtype.FieldOptionalFloat32) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *FieldTypeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case fieldtype.FieldInt: + return m.AddedInt() + case fieldtype.FieldInt8: + return m.AddedInt8() + case fieldtype.FieldInt16: + return m.AddedInt16() + case fieldtype.FieldInt32: + return m.AddedInt32() + case fieldtype.FieldInt64: + return m.AddedInt64() + case fieldtype.FieldOptionalInt: + return m.AddedOptionalInt() + case fieldtype.FieldOptionalInt8: + return m.AddedOptionalInt8() + case fieldtype.FieldOptionalInt16: + return m.AddedOptionalInt16() + case fieldtype.FieldOptionalInt32: + return m.AddedOptionalInt32() + case fieldtype.FieldOptionalInt64: + return m.AddedOptionalInt64() + case fieldtype.FieldNillableInt: + return m.AddedNillableInt() + case fieldtype.FieldNillableInt8: + return m.AddedNillableInt8() + case fieldtype.FieldNillableInt16: + return m.AddedNillableInt16() + case fieldtype.FieldNillableInt32: + return m.AddedNillableInt32() + case fieldtype.FieldNillableInt64: + return m.AddedNillableInt64() + case fieldtype.FieldValidateOptionalInt32: + return m.AddedValidateOptionalInt32() + case fieldtype.FieldOptionalUint: + return m.AddedOptionalUint() + case fieldtype.FieldOptionalUint8: + return m.AddedOptionalUint8() + case fieldtype.FieldOptionalUint16: + return m.AddedOptionalUint16() + case fieldtype.FieldOptionalUint32: + return m.AddedOptionalUint32() + case fieldtype.FieldOptionalUint64: + return m.AddedOptionalUint64() + case fieldtype.FieldOptionalFloat: + return m.AddedOptionalFloat() + case fieldtype.FieldOptionalFloat32: + return m.AddedOptionalFloat32() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FieldTypeMutation) AddField(name string, value ent.Value) error { + switch name { + case fieldtype.FieldInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt(v) + return nil + case fieldtype.FieldInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt8(v) + return nil + case fieldtype.FieldInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt16(v) + return nil + case fieldtype.FieldInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt32(v) + return nil + case fieldtype.FieldInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddInt64(v) + return nil + case fieldtype.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt(v) + return nil + case fieldtype.FieldOptionalInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt8(v) + return nil + case fieldtype.FieldOptionalInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt16(v) + return nil + case fieldtype.FieldOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt32(v) + return nil + case fieldtype.FieldOptionalInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt64(v) + return nil + case fieldtype.FieldNillableInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt(v) + return nil + case fieldtype.FieldNillableInt8: + v, ok := value.(int8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt8(v) + return nil + case fieldtype.FieldNillableInt16: + v, ok := value.(int16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt16(v) + return nil + case fieldtype.FieldNillableInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt32(v) + return nil + case fieldtype.FieldNillableInt64: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddNillableInt64(v) + return nil + case fieldtype.FieldValidateOptionalInt32: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValidateOptionalInt32(v) + return nil + case fieldtype.FieldOptionalUint: + v, ok := value.(uint) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint(v) + return nil + case fieldtype.FieldOptionalUint8: + v, ok := value.(uint8) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint8(v) + return nil + case fieldtype.FieldOptionalUint16: + v, ok := value.(uint16) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint16(v) + return nil + case fieldtype.FieldOptionalUint32: + v, ok := value.(uint32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint32(v) + return nil + case fieldtype.FieldOptionalUint64: + v, ok := value.(uint64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalUint64(v) + return nil + case fieldtype.FieldOptionalFloat: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalFloat(v) + return nil + case fieldtype.FieldOptionalFloat32: + v, ok := value.(float32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalFloat32(v) + return nil + } + return fmt.Errorf("unknown FieldType numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *FieldTypeMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[fieldtype.FieldOptionalInt] { + fields = append(fields, fieldtype.FieldOptionalInt) + } + if m.clearedFields[fieldtype.FieldOptionalInt8] { + fields = append(fields, fieldtype.FieldOptionalInt8) + } + if m.clearedFields[fieldtype.FieldOptionalInt16] { + fields = append(fields, fieldtype.FieldOptionalInt16) + } + if m.clearedFields[fieldtype.FieldOptionalInt32] { + fields = append(fields, fieldtype.FieldOptionalInt32) + } + if m.clearedFields[fieldtype.FieldOptionalInt64] { + fields = append(fields, fieldtype.FieldOptionalInt64) + } + if m.clearedFields[fieldtype.FieldNillableInt] { + fields = append(fields, fieldtype.FieldNillableInt) + } + if m.clearedFields[fieldtype.FieldNillableInt8] { + fields = append(fields, fieldtype.FieldNillableInt8) + } + if m.clearedFields[fieldtype.FieldNillableInt16] { + fields = append(fields, fieldtype.FieldNillableInt16) + } + if m.clearedFields[fieldtype.FieldNillableInt32] { + fields = append(fields, fieldtype.FieldNillableInt32) + } + if m.clearedFields[fieldtype.FieldNillableInt64] { + fields = append(fields, fieldtype.FieldNillableInt64) + } + if m.clearedFields[fieldtype.FieldValidateOptionalInt32] { + fields = append(fields, fieldtype.FieldValidateOptionalInt32) + } + if m.clearedFields[fieldtype.FieldOptionalUint] { + fields = append(fields, fieldtype.FieldOptionalUint) + } + if m.clearedFields[fieldtype.FieldOptionalUint8] { + fields = append(fields, fieldtype.FieldOptionalUint8) + } + if m.clearedFields[fieldtype.FieldOptionalUint16] { + fields = append(fields, fieldtype.FieldOptionalUint16) + } + if m.clearedFields[fieldtype.FieldOptionalUint32] { + fields = append(fields, fieldtype.FieldOptionalUint32) + } + if m.clearedFields[fieldtype.FieldOptionalUint64] { + fields = append(fields, fieldtype.FieldOptionalUint64) + } + if m.clearedFields[fieldtype.FieldState] { + fields = append(fields, fieldtype.FieldState) + } + if m.clearedFields[fieldtype.FieldOptionalFloat] { + fields = append(fields, fieldtype.FieldOptionalFloat) + } + if m.clearedFields[fieldtype.FieldOptionalFloat32] { + fields = append(fields, fieldtype.FieldOptionalFloat32) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *FieldTypeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *FieldTypeMutation) ClearField(name string) error { + switch name { + case fieldtype.FieldOptionalInt: + m.ClearOptionalInt() + return nil + case fieldtype.FieldOptionalInt8: + m.ClearOptionalInt8() + return nil + case fieldtype.FieldOptionalInt16: + m.ClearOptionalInt16() + return nil + case fieldtype.FieldOptionalInt32: + m.ClearOptionalInt32() + return nil + case fieldtype.FieldOptionalInt64: + m.ClearOptionalInt64() + return nil + case fieldtype.FieldNillableInt: + m.ClearNillableInt() + return nil + case fieldtype.FieldNillableInt8: + m.ClearNillableInt8() + return nil + case fieldtype.FieldNillableInt16: + m.ClearNillableInt16() + return nil + case fieldtype.FieldNillableInt32: + m.ClearNillableInt32() + return nil + case fieldtype.FieldNillableInt64: + m.ClearNillableInt64() + return nil + case fieldtype.FieldValidateOptionalInt32: + m.ClearValidateOptionalInt32() + return nil + case fieldtype.FieldOptionalUint: + m.ClearOptionalUint() + return nil + case fieldtype.FieldOptionalUint8: + m.ClearOptionalUint8() + return nil + case fieldtype.FieldOptionalUint16: + m.ClearOptionalUint16() + return nil + case fieldtype.FieldOptionalUint32: + m.ClearOptionalUint32() + return nil + case fieldtype.FieldOptionalUint64: + m.ClearOptionalUint64() + return nil + case fieldtype.FieldState: + m.ClearState() + return nil + case fieldtype.FieldOptionalFloat: + m.ClearOptionalFloat() + return nil + case fieldtype.FieldOptionalFloat32: + m.ClearOptionalFloat32() + return nil + } + return fmt.Errorf("unknown FieldType nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *FieldTypeMutation) ResetField(name string) error { + switch name { + case fieldtype.FieldInt: + m.ResetInt() + return nil + case fieldtype.FieldInt8: + m.ResetInt8() + return nil + case fieldtype.FieldInt16: + m.ResetInt16() + return nil + case fieldtype.FieldInt32: + m.ResetInt32() + return nil + case fieldtype.FieldInt64: + m.ResetInt64() + return nil + case fieldtype.FieldOptionalInt: + m.ResetOptionalInt() + return nil + case fieldtype.FieldOptionalInt8: + m.ResetOptionalInt8() + return nil + case fieldtype.FieldOptionalInt16: + m.ResetOptionalInt16() + return nil + case fieldtype.FieldOptionalInt32: + m.ResetOptionalInt32() + return nil + case fieldtype.FieldOptionalInt64: + m.ResetOptionalInt64() + return nil + case fieldtype.FieldNillableInt: + m.ResetNillableInt() + return nil + case fieldtype.FieldNillableInt8: + m.ResetNillableInt8() + return nil + case fieldtype.FieldNillableInt16: + m.ResetNillableInt16() + return nil + case fieldtype.FieldNillableInt32: + m.ResetNillableInt32() + return nil + case fieldtype.FieldNillableInt64: + m.ResetNillableInt64() + return nil + case fieldtype.FieldValidateOptionalInt32: + m.ResetValidateOptionalInt32() + return nil + case fieldtype.FieldOptionalUint: + m.ResetOptionalUint() + return nil + case fieldtype.FieldOptionalUint8: + m.ResetOptionalUint8() + return nil + case fieldtype.FieldOptionalUint16: + m.ResetOptionalUint16() + return nil + case fieldtype.FieldOptionalUint32: + m.ResetOptionalUint32() + return nil + case fieldtype.FieldOptionalUint64: + m.ResetOptionalUint64() + return nil + case fieldtype.FieldState: + m.ResetState() + return nil + case fieldtype.FieldOptionalFloat: + m.ResetOptionalFloat() + return nil + case fieldtype.FieldOptionalFloat32: + m.ResetOptionalFloat32() + return nil + } + return fmt.Errorf("unknown FieldType field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *FieldTypeMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *FieldTypeMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *FieldTypeMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *FieldTypeMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *FieldTypeMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *FieldTypeMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *FieldTypeMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown FieldType unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *FieldTypeMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown FieldType edge %s", name) +} + +// FileMutation represents an operation that mutate the Files +// nodes in the graph. +type FileMutation struct { + config + op Op + typ string + id *string + size *int + addsize *int + name *string + user *string + group *string + clearedFields map[string]bool + owner *string + clearedowner bool + _type *string + cleared_type bool +} + +var _ ent.Mutation = (*FileMutation)(nil) + +// newFileMutation creates new mutation for $n.Name. +func newFileMutation(c config, op Op) *FileMutation { + return &FileMutation{ + config: c, + op: op, + typ: TypeFile, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m FileMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m FileMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *FileMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetSize sets the size field. +func (m *FileMutation) SetSize(i int) { + m.size = &i + m.addsize = nil +} + +// Size returns the size value in the mutation. +func (m *FileMutation) Size() (r int, exists bool) { + v := m.size + if v == nil { + return + } + return *v, true +} + +// AddSize adds i to size. +func (m *FileMutation) AddSize(i int) { + if m.addsize != nil { + *m.addsize += i + } else { + m.addsize = &i + } +} + +// AddedSize returns the value that was added to the size field in this mutation. +func (m *FileMutation) AddedSize() (r int, exists bool) { + v := m.addsize + if v == nil { + return + } + return *v, true +} + +// ResetSize reset all changes of the size field. +func (m *FileMutation) ResetSize() { + m.size = nil + m.addsize = nil +} + +// SetName sets the name field. +func (m *FileMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *FileMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *FileMutation) ResetName() { + m.name = nil +} + +// SetUser sets the user field. +func (m *FileMutation) SetUser(s string) { + m.user = &s +} + +// User returns the user value in the mutation. +func (m *FileMutation) User() (r string, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// ClearUser clears the value of user. +func (m *FileMutation) ClearUser() { + m.user = nil + m.clearedFields[file.FieldUser] = true +} + +// UserCleared returns if the field user was cleared in this mutation. +func (m *FileMutation) UserCleared() bool { + return m.clearedFields[file.FieldUser] +} + +// ResetUser reset all changes of the user field. +func (m *FileMutation) ResetUser() { + m.user = nil + delete(m.clearedFields, file.FieldUser) +} + +// SetGroup sets the group field. +func (m *FileMutation) SetGroup(s string) { + m.group = &s +} + +// Group returns the group value in the mutation. +func (m *FileMutation) Group() (r string, exists bool) { + v := m.group + if v == nil { + return + } + return *v, true +} + +// ClearGroup clears the value of group. +func (m *FileMutation) ClearGroup() { + m.group = nil + m.clearedFields[file.FieldGroup] = true +} + +// GroupCleared returns if the field group was cleared in this mutation. +func (m *FileMutation) GroupCleared() bool { + return m.clearedFields[file.FieldGroup] +} + +// ResetGroup reset all changes of the group field. +func (m *FileMutation) ResetGroup() { + m.group = nil + delete(m.clearedFields, file.FieldGroup) +} + +// SetOwnerID sets the owner edge to User by id. +func (m *FileMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *FileMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *FileMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *FileMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *FileMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *FileMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// SetTypeID sets the type edge to FileType by id. +func (m *FileMutation) SetTypeID(id string) { + m._type = &id +} + +// ClearType clears the type edge to FileType. +func (m *FileMutation) ClearType() { + m.cleared_type = true +} + +// TypeCleared returns if the edge type was cleared. +func (m *FileMutation) TypeCleared() bool { + return m.cleared_type +} + +// TypeID returns the type id in the mutation. +func (m *FileMutation) TypeID() (id string, exists bool) { + if m._type != nil { + return *m._type, true + } + return +} + +// TypeIDs returns the type ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// TypeID instead. It exists only for internal usage by the builders. +func (m *FileMutation) TypeIDs() (ids []string) { + if id := m._type; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetType reset all changes of the type edge. +func (m *FileMutation) ResetType() { + m._type = nil + m.cleared_type = false +} + +// Op returns the operation name. +func (m *FileMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (File). +func (m *FileMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *FileMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.size != nil { + fields = append(fields, file.FieldSize) + } + if m.name != nil { + fields = append(fields, file.FieldName) + } + if m.user != nil { + fields = append(fields, file.FieldUser) + } + if m.group != nil { + fields = append(fields, file.FieldGroup) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *FileMutation) Field(name string) (ent.Value, bool) { + switch name { + case file.FieldSize: + return m.Size() + case file.FieldName: + return m.Name() + case file.FieldUser: + return m.User() + case file.FieldGroup: + return m.Group() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileMutation) SetField(name string, value ent.Value) error { + switch name { + case file.FieldSize: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSize(v) + return nil + case file.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case file.FieldUser: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUser(v) + return nil + case file.FieldGroup: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetGroup(v) + return nil + } + return fmt.Errorf("unknown File field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *FileMutation) AddedFields() []string { + var fields []string + if m.addsize != nil { + fields = append(fields, file.FieldSize) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *FileMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case file.FieldSize: + return m.AddedSize() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileMutation) AddField(name string, value ent.Value) error { + switch name { + case file.FieldSize: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSize(v) + return nil + } + return fmt.Errorf("unknown File numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *FileMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[file.FieldUser] { + fields = append(fields, file.FieldUser) + } + if m.clearedFields[file.FieldGroup] { + fields = append(fields, file.FieldGroup) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *FileMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *FileMutation) ClearField(name string) error { + switch name { + case file.FieldUser: + m.ClearUser() + return nil + case file.FieldGroup: + m.ClearGroup() + return nil + } + return fmt.Errorf("unknown File nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *FileMutation) ResetField(name string) error { + switch name { + case file.FieldSize: + m.ResetSize() + return nil + case file.FieldName: + m.ResetName() + return nil + case file.FieldUser: + m.ResetUser() + return nil + case file.FieldGroup: + m.ResetGroup() + return nil + } + return fmt.Errorf("unknown File field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *FileMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.owner != nil { + edges = append(edges, file.EdgeOwner) + } + if m._type != nil { + edges = append(edges, file.EdgeType) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *FileMutation) AddedIDs(name string) []ent.Value { + switch name { + case file.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + case file.EdgeType: + if id := m._type; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *FileMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *FileMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *FileMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedowner { + edges = append(edges, file.EdgeOwner) + } + if m.cleared_type { + edges = append(edges, file.EdgeType) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *FileMutation) EdgeCleared(name string) bool { + switch name { + case file.EdgeOwner: + return m.clearedowner + case file.EdgeType: + return m.cleared_type + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *FileMutation) ClearEdge(name string) error { + switch name { + case file.EdgeOwner: + m.ClearOwner() + return nil + case file.EdgeType: + m.ClearType() + return nil + } + return fmt.Errorf("unknown File unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *FileMutation) ResetEdge(name string) error { + switch name { + case file.EdgeOwner: + m.ResetOwner() + return nil + case file.EdgeType: + m.ResetType() + return nil + } + return fmt.Errorf("unknown File edge %s", name) +} + +// FileTypeMutation represents an operation that mutate the FileTypes +// nodes in the graph. +type FileTypeMutation struct { + config + op Op + typ string + id *string + name *string + clearedFields map[string]bool + files map[string]struct{} + removedfiles map[string]struct{} +} + +var _ ent.Mutation = (*FileTypeMutation)(nil) + +// newFileTypeMutation creates new mutation for $n.Name. +func newFileTypeMutation(c config, op Op) *FileTypeMutation { + return &FileTypeMutation{ + config: c, + op: op, + typ: TypeFileType, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m FileTypeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m FileTypeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *FileTypeMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *FileTypeMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *FileTypeMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *FileTypeMutation) ResetName() { + m.name = nil +} + +// AddFileIDs adds the files edge to File by ids. +func (m *FileTypeMutation) AddFileIDs(ids ...string) { + if m.files == nil { + m.files = make(map[string]struct{}) + } + for i := range ids { + m.files[ids[i]] = struct{}{} + } +} + +// RemoveFileIDs removes the files edge to File by ids. +func (m *FileTypeMutation) RemoveFileIDs(ids ...string) { + if m.removedfiles == nil { + m.removedfiles = make(map[string]struct{}) + } + for i := range ids { + m.removedfiles[ids[i]] = struct{}{} + } +} + +// RemovedFiles returns the removed ids of files. +func (m *FileTypeMutation) RemovedFilesIDs() (ids []string) { + for id := range m.removedfiles { + ids = append(ids, id) + } + return +} + +// FilesIDs returns the files ids in the mutation. +func (m *FileTypeMutation) FilesIDs() (ids []string) { + for id := range m.files { + ids = append(ids, id) + } + return +} + +// ResetFiles reset all changes of the files edge. +func (m *FileTypeMutation) ResetFiles() { + m.files = nil + m.removedfiles = nil +} + +// Op returns the operation name. +func (m *FileTypeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (FileType). +func (m *FileTypeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *FileTypeMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, filetype.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *FileTypeMutation) Field(name string) (ent.Value, bool) { + switch name { + case filetype.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileTypeMutation) SetField(name string, value ent.Value) error { + switch name { + case filetype.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown FileType field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *FileTypeMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *FileTypeMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *FileTypeMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown FileType numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *FileTypeMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *FileTypeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *FileTypeMutation) ClearField(name string) error { + return fmt.Errorf("unknown FileType nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *FileTypeMutation) ResetField(name string) error { + switch name { + case filetype.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown FileType field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *FileTypeMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.files != nil { + edges = append(edges, filetype.EdgeFiles) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *FileTypeMutation) AddedIDs(name string) []ent.Value { + switch name { + case filetype.EdgeFiles: + ids := make([]ent.Value, 0, len(m.files)) + for id := range m.files { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *FileTypeMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedfiles != nil { + edges = append(edges, filetype.EdgeFiles) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *FileTypeMutation) RemovedIDs(name string) []ent.Value { + switch name { + case filetype.EdgeFiles: + ids := make([]ent.Value, 0, len(m.removedfiles)) + for id := range m.removedfiles { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *FileTypeMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *FileTypeMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *FileTypeMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown FileType unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *FileTypeMutation) ResetEdge(name string) error { + switch name { + case filetype.EdgeFiles: + m.ResetFiles() + return nil + } + return fmt.Errorf("unknown FileType edge %s", name) +} + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *string + active *bool + expire *time.Time + _type *string + max_users *int + addmax_users *int + name *string + clearedFields map[string]bool + files map[string]struct{} + removedfiles map[string]struct{} + blocked map[string]struct{} + removedblocked map[string]struct{} + users map[string]struct{} + removedusers map[string]struct{} + info *string + clearedinfo bool +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetActive sets the active field. +func (m *GroupMutation) SetActive(b bool) { + m.active = &b +} + +// Active returns the active value in the mutation. +func (m *GroupMutation) Active() (r bool, exists bool) { + v := m.active + if v == nil { + return + } + return *v, true +} + +// ResetActive reset all changes of the active field. +func (m *GroupMutation) ResetActive() { + m.active = nil +} + +// SetExpire sets the expire field. +func (m *GroupMutation) SetExpire(t time.Time) { + m.expire = &t +} + +// Expire returns the expire value in the mutation. +func (m *GroupMutation) Expire() (r time.Time, exists bool) { + v := m.expire + if v == nil { + return + } + return *v, true +} + +// ResetExpire reset all changes of the expire field. +func (m *GroupMutation) ResetExpire() { + m.expire = nil +} + +// SetType sets the type field. +func (m *GroupMutation) SetType(s string) { + m._type = &s +} + +// GetType returns the type value in the mutation. +func (m *GroupMutation) GetType() (r string, exists bool) { + v := m._type + if v == nil { + return + } + return *v, true +} + +// ClearType clears the value of type. +func (m *GroupMutation) ClearType() { + m._type = nil + m.clearedFields[group.FieldType] = true +} + +// TypeCleared returns if the field type was cleared in this mutation. +func (m *GroupMutation) TypeCleared() bool { + return m.clearedFields[group.FieldType] +} + +// ResetType reset all changes of the type field. +func (m *GroupMutation) ResetType() { + m._type = nil + delete(m.clearedFields, group.FieldType) +} + +// SetMaxUsers sets the max_users field. +func (m *GroupMutation) SetMaxUsers(i int) { + m.max_users = &i + m.addmax_users = nil +} + +// MaxUsers returns the max_users value in the mutation. +func (m *GroupMutation) MaxUsers() (r int, exists bool) { + v := m.max_users + if v == nil { + return + } + return *v, true +} + +// AddMaxUsers adds i to max_users. +func (m *GroupMutation) AddMaxUsers(i int) { + if m.addmax_users != nil { + *m.addmax_users += i + } else { + m.addmax_users = &i + } +} + +// AddedMaxUsers returns the value that was added to the max_users field in this mutation. +func (m *GroupMutation) AddedMaxUsers() (r int, exists bool) { + v := m.addmax_users + if v == nil { + return + } + return *v, true +} + +// ClearMaxUsers clears the value of max_users. +func (m *GroupMutation) ClearMaxUsers() { + m.max_users = nil + m.addmax_users = nil + m.clearedFields[group.FieldMaxUsers] = true +} + +// MaxUsersCleared returns if the field max_users was cleared in this mutation. +func (m *GroupMutation) MaxUsersCleared() bool { + return m.clearedFields[group.FieldMaxUsers] +} + +// ResetMaxUsers reset all changes of the max_users field. +func (m *GroupMutation) ResetMaxUsers() { + m.max_users = nil + m.addmax_users = nil + delete(m.clearedFields, group.FieldMaxUsers) +} + +// SetName sets the name field. +func (m *GroupMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *GroupMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *GroupMutation) ResetName() { + m.name = nil +} + +// AddFileIDs adds the files edge to File by ids. +func (m *GroupMutation) AddFileIDs(ids ...string) { + if m.files == nil { + m.files = make(map[string]struct{}) + } + for i := range ids { + m.files[ids[i]] = struct{}{} + } +} + +// RemoveFileIDs removes the files edge to File by ids. +func (m *GroupMutation) RemoveFileIDs(ids ...string) { + if m.removedfiles == nil { + m.removedfiles = make(map[string]struct{}) + } + for i := range ids { + m.removedfiles[ids[i]] = struct{}{} + } +} + +// RemovedFiles returns the removed ids of files. +func (m *GroupMutation) RemovedFilesIDs() (ids []string) { + for id := range m.removedfiles { + ids = append(ids, id) + } + return +} + +// FilesIDs returns the files ids in the mutation. +func (m *GroupMutation) FilesIDs() (ids []string) { + for id := range m.files { + ids = append(ids, id) + } + return +} + +// ResetFiles reset all changes of the files edge. +func (m *GroupMutation) ResetFiles() { + m.files = nil + m.removedfiles = nil +} + +// AddBlockedIDs adds the blocked edge to User by ids. +func (m *GroupMutation) AddBlockedIDs(ids ...string) { + if m.blocked == nil { + m.blocked = make(map[string]struct{}) + } + for i := range ids { + m.blocked[ids[i]] = struct{}{} + } +} + +// RemoveBlockedIDs removes the blocked edge to User by ids. +func (m *GroupMutation) RemoveBlockedIDs(ids ...string) { + if m.removedblocked == nil { + m.removedblocked = make(map[string]struct{}) + } + for i := range ids { + m.removedblocked[ids[i]] = struct{}{} + } +} + +// RemovedBlocked returns the removed ids of blocked. +func (m *GroupMutation) RemovedBlockedIDs() (ids []string) { + for id := range m.removedblocked { + ids = append(ids, id) + } + return +} + +// BlockedIDs returns the blocked ids in the mutation. +func (m *GroupMutation) BlockedIDs() (ids []string) { + for id := range m.blocked { + ids = append(ids, id) + } + return +} + +// ResetBlocked reset all changes of the blocked edge. +func (m *GroupMutation) ResetBlocked() { + m.blocked = nil + m.removedblocked = nil +} + +// AddUserIDs adds the users edge to User by ids. +func (m *GroupMutation) AddUserIDs(ids ...string) { + if m.users == nil { + m.users = make(map[string]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// RemoveUserIDs removes the users edge to User by ids. +func (m *GroupMutation) RemoveUserIDs(ids ...string) { + if m.removedusers == nil { + m.removedusers = make(map[string]struct{}) + } + for i := range ids { + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed ids of users. +func (m *GroupMutation) RemovedUsersIDs() (ids []string) { + for id := range m.removedusers { + ids = append(ids, id) + } + return +} + +// UsersIDs returns the users ids in the mutation. +func (m *GroupMutation) UsersIDs() (ids []string) { + for id := range m.users { + ids = append(ids, id) + } + return +} + +// ResetUsers reset all changes of the users edge. +func (m *GroupMutation) ResetUsers() { + m.users = nil + m.removedusers = nil +} + +// SetInfoID sets the info edge to GroupInfo by id. +func (m *GroupMutation) SetInfoID(id string) { + m.info = &id +} + +// ClearInfo clears the info edge to GroupInfo. +func (m *GroupMutation) ClearInfo() { + m.clearedinfo = true +} + +// InfoCleared returns if the edge info was cleared. +func (m *GroupMutation) InfoCleared() bool { + return m.clearedinfo +} + +// InfoID returns the info id in the mutation. +func (m *GroupMutation) InfoID() (id string, exists bool) { + if m.info != nil { + return *m.info, true + } + return +} + +// InfoIDs returns the info ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// InfoID instead. It exists only for internal usage by the builders. +func (m *GroupMutation) InfoIDs() (ids []string) { + if id := m.info; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetInfo reset all changes of the info edge. +func (m *GroupMutation) ResetInfo() { + m.info = nil + m.clearedinfo = false +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.active != nil { + fields = append(fields, group.FieldActive) + } + if m.expire != nil { + fields = append(fields, group.FieldExpire) + } + if m._type != nil { + fields = append(fields, group.FieldType) + } + if m.max_users != nil { + fields = append(fields, group.FieldMaxUsers) + } + if m.name != nil { + fields = append(fields, group.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + case group.FieldActive: + return m.Active() + case group.FieldExpire: + return m.Expire() + case group.FieldType: + return m.GetType() + case group.FieldMaxUsers: + return m.MaxUsers() + case group.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + case group.FieldActive: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetActive(v) + return nil + case group.FieldExpire: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExpire(v) + return nil + case group.FieldType: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetType(v) + return nil + case group.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMaxUsers(v) + return nil + case group.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + var fields []string + if m.addmax_users != nil { + fields = append(fields, group.FieldMaxUsers) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case group.FieldMaxUsers: + return m.AddedMaxUsers() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + case group.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMaxUsers(v) + return nil + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[group.FieldType] { + fields = append(fields, group.FieldType) + } + if m.clearedFields[group.FieldMaxUsers] { + fields = append(fields, group.FieldMaxUsers) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + switch name { + case group.FieldType: + m.ClearType() + return nil + case group.FieldMaxUsers: + m.ClearMaxUsers() + return nil + } + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + case group.FieldActive: + m.ResetActive() + return nil + case group.FieldExpire: + m.ResetExpire() + return nil + case group.FieldType: + m.ResetType() + return nil + case group.FieldMaxUsers: + m.ResetMaxUsers() + return nil + case group.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 4) + if m.files != nil { + edges = append(edges, group.EdgeFiles) + } + if m.blocked != nil { + edges = append(edges, group.EdgeBlocked) + } + if m.users != nil { + edges = append(edges, group.EdgeUsers) + } + if m.info != nil { + edges = append(edges, group.EdgeInfo) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + case group.EdgeFiles: + ids := make([]ent.Value, 0, len(m.files)) + for id := range m.files { + ids = append(ids, id) + } + return ids + case group.EdgeBlocked: + ids := make([]ent.Value, 0, len(m.blocked)) + for id := range m.blocked { + ids = append(ids, id) + } + return ids + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) + } + return ids + case group.EdgeInfo: + if id := m.info; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 4) + if m.removedfiles != nil { + edges = append(edges, group.EdgeFiles) + } + if m.removedblocked != nil { + edges = append(edges, group.EdgeBlocked) + } + if m.removedusers != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + case group.EdgeFiles: + ids := make([]ent.Value, 0, len(m.removedfiles)) + for id := range m.removedfiles { + ids = append(ids, id) + } + return ids + case group.EdgeBlocked: + ids := make([]ent.Value, 0, len(m.removedblocked)) + for id := range m.removedblocked { + ids = append(ids, id) + } + return ids + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 4) + if m.clearedinfo { + edges = append(edges, group.EdgeInfo) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + case group.EdgeInfo: + return m.clearedinfo + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + switch name { + case group.EdgeInfo: + m.ClearInfo() + return nil + } + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + case group.EdgeFiles: + m.ResetFiles() + return nil + case group.EdgeBlocked: + m.ResetBlocked() + return nil + case group.EdgeUsers: + m.ResetUsers() + return nil + case group.EdgeInfo: + m.ResetInfo() + return nil + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// GroupInfoMutation represents an operation that mutate the GroupInfos +// nodes in the graph. +type GroupInfoMutation struct { + config + op Op + typ string + id *string + desc *string + max_users *int + addmax_users *int + clearedFields map[string]bool + groups map[string]struct{} + removedgroups map[string]struct{} +} + +var _ ent.Mutation = (*GroupInfoMutation)(nil) + +// newGroupInfoMutation creates new mutation for $n.Name. +func newGroupInfoMutation(c config, op Op) *GroupInfoMutation { + return &GroupInfoMutation{ + config: c, + op: op, + typ: TypeGroupInfo, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupInfoMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupInfoMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupInfoMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetDesc sets the desc field. +func (m *GroupInfoMutation) SetDesc(s string) { + m.desc = &s +} + +// Desc returns the desc value in the mutation. +func (m *GroupInfoMutation) Desc() (r string, exists bool) { + v := m.desc + if v == nil { + return + } + return *v, true +} + +// ResetDesc reset all changes of the desc field. +func (m *GroupInfoMutation) ResetDesc() { + m.desc = nil +} + +// SetMaxUsers sets the max_users field. +func (m *GroupInfoMutation) SetMaxUsers(i int) { + m.max_users = &i + m.addmax_users = nil +} + +// MaxUsers returns the max_users value in the mutation. +func (m *GroupInfoMutation) MaxUsers() (r int, exists bool) { + v := m.max_users + if v == nil { + return + } + return *v, true +} + +// AddMaxUsers adds i to max_users. +func (m *GroupInfoMutation) AddMaxUsers(i int) { + if m.addmax_users != nil { + *m.addmax_users += i + } else { + m.addmax_users = &i + } +} + +// AddedMaxUsers returns the value that was added to the max_users field in this mutation. +func (m *GroupInfoMutation) AddedMaxUsers() (r int, exists bool) { + v := m.addmax_users + if v == nil { + return + } + return *v, true +} + +// ResetMaxUsers reset all changes of the max_users field. +func (m *GroupInfoMutation) ResetMaxUsers() { + m.max_users = nil + m.addmax_users = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *GroupInfoMutation) AddGroupIDs(ids ...string) { + if m.groups == nil { + m.groups = make(map[string]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *GroupInfoMutation) RemoveGroupIDs(ids ...string) { + if m.removedgroups == nil { + m.removedgroups = make(map[string]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *GroupInfoMutation) RemovedGroupsIDs() (ids []string) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *GroupInfoMutation) GroupsIDs() (ids []string) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *GroupInfoMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// Op returns the operation name. +func (m *GroupInfoMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (GroupInfo). +func (m *GroupInfoMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupInfoMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.desc != nil { + fields = append(fields, groupinfo.FieldDesc) + } + if m.max_users != nil { + fields = append(fields, groupinfo.FieldMaxUsers) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupInfoMutation) Field(name string) (ent.Value, bool) { + switch name { + case groupinfo.FieldDesc: + return m.Desc() + case groupinfo.FieldMaxUsers: + return m.MaxUsers() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupInfoMutation) SetField(name string, value ent.Value) error { + switch name { + case groupinfo.FieldDesc: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDesc(v) + return nil + case groupinfo.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMaxUsers(v) + return nil + } + return fmt.Errorf("unknown GroupInfo field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupInfoMutation) AddedFields() []string { + var fields []string + if m.addmax_users != nil { + fields = append(fields, groupinfo.FieldMaxUsers) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupInfoMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case groupinfo.FieldMaxUsers: + return m.AddedMaxUsers() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupInfoMutation) AddField(name string, value ent.Value) error { + switch name { + case groupinfo.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMaxUsers(v) + return nil + } + return fmt.Errorf("unknown GroupInfo numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupInfoMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupInfoMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupInfoMutation) ClearField(name string) error { + return fmt.Errorf("unknown GroupInfo nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupInfoMutation) ResetField(name string) error { + switch name { + case groupinfo.FieldDesc: + m.ResetDesc() + return nil + case groupinfo.FieldMaxUsers: + m.ResetMaxUsers() + return nil + } + return fmt.Errorf("unknown GroupInfo field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupInfoMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.groups != nil { + edges = append(edges, groupinfo.EdgeGroups) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupInfoMutation) AddedIDs(name string) []ent.Value { + switch name { + case groupinfo.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupInfoMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedgroups != nil { + edges = append(edges, groupinfo.EdgeGroups) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupInfoMutation) RemovedIDs(name string) []ent.Value { + switch name { + case groupinfo.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupInfoMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupInfoMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupInfoMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown GroupInfo unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupInfoMutation) ResetEdge(name string) error { + switch name { + case groupinfo.EdgeGroups: + m.ResetGroups() + return nil + } + return fmt.Errorf("unknown GroupInfo edge %s", name) +} + +// ItemMutation represents an operation that mutate the Items +// nodes in the graph. +type ItemMutation struct { + config + op Op + typ string + id *string + clearedFields map[string]bool +} + +var _ ent.Mutation = (*ItemMutation)(nil) + +// newItemMutation creates new mutation for $n.Name. +func newItemMutation(c config, op Op) *ItemMutation { + return &ItemMutation{ + config: c, + op: op, + typ: TypeItem, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m ItemMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m ItemMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *ItemMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// Op returns the operation name. +func (m *ItemMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Item). +func (m *ItemMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *ItemMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *ItemMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *ItemMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Item field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *ItemMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *ItemMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *ItemMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Item numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *ItemMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *ItemMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *ItemMutation) ClearField(name string) error { + return fmt.Errorf("unknown Item nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *ItemMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Item field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *ItemMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *ItemMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *ItemMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *ItemMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *ItemMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *ItemMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *ItemMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Item unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *ItemMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Item edge %s", name) +} + +// NodeMutation represents an operation that mutate the Nodes +// nodes in the graph. +type NodeMutation struct { + config + op Op + typ string + id *string + value *int + addvalue *int + clearedFields map[string]bool + prev *string + clearedprev bool + next *string + clearednext bool +} + +var _ ent.Mutation = (*NodeMutation)(nil) + +// newNodeMutation creates new mutation for $n.Name. +func newNodeMutation(c config, op Op) *NodeMutation { + return &NodeMutation{ + config: c, + op: op, + typ: TypeNode, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m NodeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m NodeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *NodeMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetValue sets the value field. +func (m *NodeMutation) SetValue(i int) { + m.value = &i + m.addvalue = nil +} + +// Value returns the value value in the mutation. +func (m *NodeMutation) Value() (r int, exists bool) { + v := m.value + if v == nil { + return + } + return *v, true +} + +// AddValue adds i to value. +func (m *NodeMutation) AddValue(i int) { + if m.addvalue != nil { + *m.addvalue += i + } else { + m.addvalue = &i + } +} + +// AddedValue returns the value that was added to the value field in this mutation. +func (m *NodeMutation) AddedValue() (r int, exists bool) { + v := m.addvalue + if v == nil { + return + } + return *v, true +} + +// ClearValue clears the value of value. +func (m *NodeMutation) ClearValue() { + m.value = nil + m.addvalue = nil + m.clearedFields[node.FieldValue] = true +} + +// ValueCleared returns if the field value was cleared in this mutation. +func (m *NodeMutation) ValueCleared() bool { + return m.clearedFields[node.FieldValue] +} + +// ResetValue reset all changes of the value field. +func (m *NodeMutation) ResetValue() { + m.value = nil + m.addvalue = nil + delete(m.clearedFields, node.FieldValue) +} + +// SetPrevID sets the prev edge to Node by id. +func (m *NodeMutation) SetPrevID(id string) { + m.prev = &id +} + +// ClearPrev clears the prev edge to Node. +func (m *NodeMutation) ClearPrev() { + m.clearedprev = true +} + +// PrevCleared returns if the edge prev was cleared. +func (m *NodeMutation) PrevCleared() bool { + return m.clearedprev +} + +// PrevID returns the prev id in the mutation. +func (m *NodeMutation) PrevID() (id string, exists bool) { + if m.prev != nil { + return *m.prev, true + } + return +} + +// PrevIDs returns the prev ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// PrevID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) PrevIDs() (ids []string) { + if id := m.prev; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetPrev reset all changes of the prev edge. +func (m *NodeMutation) ResetPrev() { + m.prev = nil + m.clearedprev = false +} + +// SetNextID sets the next edge to Node by id. +func (m *NodeMutation) SetNextID(id string) { + m.next = &id +} + +// ClearNext clears the next edge to Node. +func (m *NodeMutation) ClearNext() { + m.clearednext = true +} + +// NextCleared returns if the edge next was cleared. +func (m *NodeMutation) NextCleared() bool { + return m.clearednext +} + +// NextID returns the next id in the mutation. +func (m *NodeMutation) NextID() (id string, exists bool) { + if m.next != nil { + return *m.next, true + } + return +} + +// NextIDs returns the next ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// NextID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) NextIDs() (ids []string) { + if id := m.next; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetNext reset all changes of the next edge. +func (m *NodeMutation) ResetNext() { + m.next = nil + m.clearednext = false +} + +// Op returns the operation name. +func (m *NodeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Node). +func (m *NodeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *NodeMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.value != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *NodeMutation) Field(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.Value() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) SetField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValue(v) + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *NodeMutation) AddedFields() []string { + var fields []string + if m.addvalue != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *NodeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.AddedValue() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) AddField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValue(v) + return nil + } + return fmt.Errorf("unknown Node numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *NodeMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[node.FieldValue] { + fields = append(fields, node.FieldValue) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *NodeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *NodeMutation) ClearField(name string) error { + switch name { + case node.FieldValue: + m.ClearValue() + return nil + } + return fmt.Errorf("unknown Node nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *NodeMutation) ResetField(name string) error { + switch name { + case node.FieldValue: + m.ResetValue() + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *NodeMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.prev != nil { + edges = append(edges, node.EdgePrev) + } + if m.next != nil { + edges = append(edges, node.EdgeNext) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *NodeMutation) AddedIDs(name string) []ent.Value { + switch name { + case node.EdgePrev: + if id := m.prev; id != nil { + return []ent.Value{*id} + } + case node.EdgeNext: + if id := m.next; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *NodeMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *NodeMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *NodeMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedprev { + edges = append(edges, node.EdgePrev) + } + if m.clearednext { + edges = append(edges, node.EdgeNext) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *NodeMutation) EdgeCleared(name string) bool { + switch name { + case node.EdgePrev: + return m.clearedprev + case node.EdgeNext: + return m.clearednext + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *NodeMutation) ClearEdge(name string) error { + switch name { + case node.EdgePrev: + m.ClearPrev() + return nil + case node.EdgeNext: + m.ClearNext() + return nil + } + return fmt.Errorf("unknown Node unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *NodeMutation) ResetEdge(name string) error { + switch name { + case node.EdgePrev: + m.ResetPrev() + return nil + case node.EdgeNext: + m.ResetNext() + return nil + } + return fmt.Errorf("unknown Node edge %s", name) +} + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *string + name *string + clearedFields map[string]bool + team *string + clearedteam bool + owner *string + clearedowner bool +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *PetMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *PetMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *PetMutation) ResetName() { + m.name = nil +} + +// SetTeamID sets the team edge to User by id. +func (m *PetMutation) SetTeamID(id string) { + m.team = &id +} + +// ClearTeam clears the team edge to User. +func (m *PetMutation) ClearTeam() { + m.clearedteam = true +} + +// TeamCleared returns if the edge team was cleared. +func (m *PetMutation) TeamCleared() bool { + return m.clearedteam +} + +// TeamID returns the team id in the mutation. +func (m *PetMutation) TeamID() (id string, exists bool) { + if m.team != nil { + return *m.team, true + } + return +} + +// TeamIDs returns the team ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// TeamID instead. It exists only for internal usage by the builders. +func (m *PetMutation) TeamIDs() (ids []string) { + if id := m.team; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetTeam reset all changes of the team edge. +func (m *PetMutation) ResetTeam() { + m.team = nil + m.clearedteam = false +} + +// SetOwnerID sets the owner edge to User by id. +func (m *PetMutation) SetOwnerID(id string) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *PetMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *PetMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *PetMutation) OwnerID() (id string, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *PetMutation) OwnerIDs() (ids []string) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *PetMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, pet.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + case pet.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + case pet.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + case pet.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.team != nil { + edges = append(edges, pet.EdgeTeam) + } + if m.owner != nil { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + case pet.EdgeTeam: + if id := m.team; id != nil { + return []ent.Value{*id} + } + case pet.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedteam { + edges = append(edges, pet.EdgeTeam) + } + if m.clearedowner { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + case pet.EdgeTeam: + return m.clearedteam + case pet.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + switch name { + case pet.EdgeTeam: + m.ClearTeam() + return nil + case pet.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + case pet.EdgeTeam: + m.ResetTeam() + return nil + case pet.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// SpecMutation represents an operation that mutate the Specs +// nodes in the graph. +type SpecMutation struct { + config + op Op + typ string + id *string + clearedFields map[string]bool + card map[string]struct{} + removedcard map[string]struct{} +} + +var _ ent.Mutation = (*SpecMutation)(nil) + +// newSpecMutation creates new mutation for $n.Name. +func newSpecMutation(c config, op Op) *SpecMutation { + return &SpecMutation{ + config: c, + op: op, + typ: TypeSpec, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m SpecMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m SpecMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *SpecMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// AddCardIDs adds the card edge to Card by ids. +func (m *SpecMutation) AddCardIDs(ids ...string) { + if m.card == nil { + m.card = make(map[string]struct{}) + } + for i := range ids { + m.card[ids[i]] = struct{}{} + } +} + +// RemoveCardIDs removes the card edge to Card by ids. +func (m *SpecMutation) RemoveCardIDs(ids ...string) { + if m.removedcard == nil { + m.removedcard = make(map[string]struct{}) + } + for i := range ids { + m.removedcard[ids[i]] = struct{}{} + } +} + +// RemovedCard returns the removed ids of card. +func (m *SpecMutation) RemovedCardIDs() (ids []string) { + for id := range m.removedcard { + ids = append(ids, id) + } + return +} + +// CardIDs returns the card ids in the mutation. +func (m *SpecMutation) CardIDs() (ids []string) { + for id := range m.card { + ids = append(ids, id) + } + return +} + +// ResetCard reset all changes of the card edge. +func (m *SpecMutation) ResetCard() { + m.card = nil + m.removedcard = nil +} + +// Op returns the operation name. +func (m *SpecMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Spec). +func (m *SpecMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *SpecMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *SpecMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *SpecMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Spec field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *SpecMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *SpecMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *SpecMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Spec numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *SpecMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *SpecMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *SpecMutation) ClearField(name string) error { + return fmt.Errorf("unknown Spec nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *SpecMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Spec field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *SpecMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.card != nil { + edges = append(edges, spec.EdgeCard) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *SpecMutation) AddedIDs(name string) []ent.Value { + switch name { + case spec.EdgeCard: + ids := make([]ent.Value, 0, len(m.card)) + for id := range m.card { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *SpecMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedcard != nil { + edges = append(edges, spec.EdgeCard) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *SpecMutation) RemovedIDs(name string) []ent.Value { + switch name { + case spec.EdgeCard: + ids := make([]ent.Value, 0, len(m.removedcard)) + for id := range m.removedcard { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *SpecMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *SpecMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *SpecMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Spec unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *SpecMutation) ResetEdge(name string) error { + switch name { + case spec.EdgeCard: + m.ResetCard() + return nil + } + return fmt.Errorf("unknown Spec edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *string + optional_int *int + addoptional_int *int + age *int + addage *int + name *string + last *string + nickname *string + phone *string + password *string + role *user.Role + clearedFields map[string]bool + card *string + clearedcard bool + pets map[string]struct{} + removedpets map[string]struct{} + files map[string]struct{} + removedfiles map[string]struct{} + groups map[string]struct{} + removedgroups map[string]struct{} + friends map[string]struct{} + removedfriends map[string]struct{} + followers map[string]struct{} + removedfollowers map[string]struct{} + following map[string]struct{} + removedfollowing map[string]struct{} + team *string + clearedteam bool + spouse *string + clearedspouse bool + children map[string]struct{} + removedchildren map[string]struct{} + parent *string + clearedparent bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id string, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetOptionalInt sets the optional_int field. +func (m *UserMutation) SetOptionalInt(i int) { + m.optional_int = &i + m.addoptional_int = nil +} + +// OptionalInt returns the optional_int value in the mutation. +func (m *UserMutation) OptionalInt() (r int, exists bool) { + v := m.optional_int + if v == nil { + return + } + return *v, true +} + +// AddOptionalInt adds i to optional_int. +func (m *UserMutation) AddOptionalInt(i int) { + if m.addoptional_int != nil { + *m.addoptional_int += i + } else { + m.addoptional_int = &i + } +} + +// AddedOptionalInt returns the value that was added to the optional_int field in this mutation. +func (m *UserMutation) AddedOptionalInt() (r int, exists bool) { + v := m.addoptional_int + if v == nil { + return + } + return *v, true +} + +// ClearOptionalInt clears the value of optional_int. +func (m *UserMutation) ClearOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + m.clearedFields[user.FieldOptionalInt] = true +} + +// OptionalIntCleared returns if the field optional_int was cleared in this mutation. +func (m *UserMutation) OptionalIntCleared() bool { + return m.clearedFields[user.FieldOptionalInt] +} + +// ResetOptionalInt reset all changes of the optional_int field. +func (m *UserMutation) ResetOptionalInt() { + m.optional_int = nil + m.addoptional_int = nil + delete(m.clearedFields, user.FieldOptionalInt) +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetLast sets the last field. +func (m *UserMutation) SetLast(s string) { + m.last = &s +} + +// Last returns the last value in the mutation. +func (m *UserMutation) Last() (r string, exists bool) { + v := m.last + if v == nil { + return + } + return *v, true +} + +// ResetLast reset all changes of the last field. +func (m *UserMutation) ResetLast() { + m.last = nil +} + +// SetNickname sets the nickname field. +func (m *UserMutation) SetNickname(s string) { + m.nickname = &s +} + +// Nickname returns the nickname value in the mutation. +func (m *UserMutation) Nickname() (r string, exists bool) { + v := m.nickname + if v == nil { + return + } + return *v, true +} + +// ClearNickname clears the value of nickname. +func (m *UserMutation) ClearNickname() { + m.nickname = nil + m.clearedFields[user.FieldNickname] = true +} + +// NicknameCleared returns if the field nickname was cleared in this mutation. +func (m *UserMutation) NicknameCleared() bool { + return m.clearedFields[user.FieldNickname] +} + +// ResetNickname reset all changes of the nickname field. +func (m *UserMutation) ResetNickname() { + m.nickname = nil + delete(m.clearedFields, user.FieldNickname) +} + +// SetPhone sets the phone field. +func (m *UserMutation) SetPhone(s string) { + m.phone = &s +} + +// Phone returns the phone value in the mutation. +func (m *UserMutation) Phone() (r string, exists bool) { + v := m.phone + if v == nil { + return + } + return *v, true +} + +// ClearPhone clears the value of phone. +func (m *UserMutation) ClearPhone() { + m.phone = nil + m.clearedFields[user.FieldPhone] = true +} + +// PhoneCleared returns if the field phone was cleared in this mutation. +func (m *UserMutation) PhoneCleared() bool { + return m.clearedFields[user.FieldPhone] +} + +// ResetPhone reset all changes of the phone field. +func (m *UserMutation) ResetPhone() { + m.phone = nil + delete(m.clearedFields, user.FieldPhone) +} + +// SetPassword sets the password field. +func (m *UserMutation) SetPassword(s string) { + m.password = &s +} + +// Password returns the password value in the mutation. +func (m *UserMutation) Password() (r string, exists bool) { + v := m.password + if v == nil { + return + } + return *v, true +} + +// ClearPassword clears the value of password. +func (m *UserMutation) ClearPassword() { + m.password = nil + m.clearedFields[user.FieldPassword] = true +} + +// PasswordCleared returns if the field password was cleared in this mutation. +func (m *UserMutation) PasswordCleared() bool { + return m.clearedFields[user.FieldPassword] +} + +// ResetPassword reset all changes of the password field. +func (m *UserMutation) ResetPassword() { + m.password = nil + delete(m.clearedFields, user.FieldPassword) +} + +// SetRole sets the role field. +func (m *UserMutation) SetRole(u user.Role) { + m.role = &u +} + +// Role returns the role value in the mutation. +func (m *UserMutation) Role() (r user.Role, exists bool) { + v := m.role + if v == nil { + return + } + return *v, true +} + +// ResetRole reset all changes of the role field. +func (m *UserMutation) ResetRole() { + m.role = nil +} + +// SetCardID sets the card edge to Card by id. +func (m *UserMutation) SetCardID(id string) { + m.card = &id +} + +// ClearCard clears the card edge to Card. +func (m *UserMutation) ClearCard() { + m.clearedcard = true +} + +// CardCleared returns if the edge card was cleared. +func (m *UserMutation) CardCleared() bool { + return m.clearedcard +} + +// CardID returns the card id in the mutation. +func (m *UserMutation) CardID() (id string, exists bool) { + if m.card != nil { + return *m.card, true + } + return +} + +// CardIDs returns the card ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// CardID instead. It exists only for internal usage by the builders. +func (m *UserMutation) CardIDs() (ids []string) { + if id := m.card; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetCard reset all changes of the card edge. +func (m *UserMutation) ResetCard() { + m.card = nil + m.clearedcard = false +} + +// AddPetIDs adds the pets edge to Pet by ids. +func (m *UserMutation) AddPetIDs(ids ...string) { + if m.pets == nil { + m.pets = make(map[string]struct{}) + } + for i := range ids { + m.pets[ids[i]] = struct{}{} + } +} + +// RemovePetIDs removes the pets edge to Pet by ids. +func (m *UserMutation) RemovePetIDs(ids ...string) { + if m.removedpets == nil { + m.removedpets = make(map[string]struct{}) + } + for i := range ids { + m.removedpets[ids[i]] = struct{}{} + } +} + +// RemovedPets returns the removed ids of pets. +func (m *UserMutation) RemovedPetsIDs() (ids []string) { + for id := range m.removedpets { + ids = append(ids, id) + } + return +} + +// PetsIDs returns the pets ids in the mutation. +func (m *UserMutation) PetsIDs() (ids []string) { + for id := range m.pets { + ids = append(ids, id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.removedpets = nil +} + +// AddFileIDs adds the files edge to File by ids. +func (m *UserMutation) AddFileIDs(ids ...string) { + if m.files == nil { + m.files = make(map[string]struct{}) + } + for i := range ids { + m.files[ids[i]] = struct{}{} + } +} + +// RemoveFileIDs removes the files edge to File by ids. +func (m *UserMutation) RemoveFileIDs(ids ...string) { + if m.removedfiles == nil { + m.removedfiles = make(map[string]struct{}) + } + for i := range ids { + m.removedfiles[ids[i]] = struct{}{} + } +} + +// RemovedFiles returns the removed ids of files. +func (m *UserMutation) RemovedFilesIDs() (ids []string) { + for id := range m.removedfiles { + ids = append(ids, id) + } + return +} + +// FilesIDs returns the files ids in the mutation. +func (m *UserMutation) FilesIDs() (ids []string) { + for id := range m.files { + ids = append(ids, id) + } + return +} + +// ResetFiles reset all changes of the files edge. +func (m *UserMutation) ResetFiles() { + m.files = nil + m.removedfiles = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *UserMutation) AddGroupIDs(ids ...string) { + if m.groups == nil { + m.groups = make(map[string]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *UserMutation) RemoveGroupIDs(ids ...string) { + if m.removedgroups == nil { + m.removedgroups = make(map[string]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *UserMutation) RemovedGroupsIDs() (ids []string) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *UserMutation) GroupsIDs() (ids []string) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *UserMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// AddFriendIDs adds the friends edge to User by ids. +func (m *UserMutation) AddFriendIDs(ids ...string) { + if m.friends == nil { + m.friends = make(map[string]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (m *UserMutation) RemoveFriendIDs(ids ...string) { + if m.removedfriends == nil { + m.removedfriends = make(map[string]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *UserMutation) RemovedFriendsIDs() (ids []string) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *UserMutation) FriendsIDs() (ids []string) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *UserMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// AddFollowerIDs adds the followers edge to User by ids. +func (m *UserMutation) AddFollowerIDs(ids ...string) { + if m.followers == nil { + m.followers = make(map[string]struct{}) + } + for i := range ids { + m.followers[ids[i]] = struct{}{} + } +} + +// RemoveFollowerIDs removes the followers edge to User by ids. +func (m *UserMutation) RemoveFollowerIDs(ids ...string) { + if m.removedfollowers == nil { + m.removedfollowers = make(map[string]struct{}) + } + for i := range ids { + m.removedfollowers[ids[i]] = struct{}{} + } +} + +// RemovedFollowers returns the removed ids of followers. +func (m *UserMutation) RemovedFollowersIDs() (ids []string) { + for id := range m.removedfollowers { + ids = append(ids, id) + } + return +} + +// FollowersIDs returns the followers ids in the mutation. +func (m *UserMutation) FollowersIDs() (ids []string) { + for id := range m.followers { + ids = append(ids, id) + } + return +} + +// ResetFollowers reset all changes of the followers edge. +func (m *UserMutation) ResetFollowers() { + m.followers = nil + m.removedfollowers = nil +} + +// AddFollowingIDs adds the following edge to User by ids. +func (m *UserMutation) AddFollowingIDs(ids ...string) { + if m.following == nil { + m.following = make(map[string]struct{}) + } + for i := range ids { + m.following[ids[i]] = struct{}{} + } +} + +// RemoveFollowingIDs removes the following edge to User by ids. +func (m *UserMutation) RemoveFollowingIDs(ids ...string) { + if m.removedfollowing == nil { + m.removedfollowing = make(map[string]struct{}) + } + for i := range ids { + m.removedfollowing[ids[i]] = struct{}{} + } +} + +// RemovedFollowing returns the removed ids of following. +func (m *UserMutation) RemovedFollowingIDs() (ids []string) { + for id := range m.removedfollowing { + ids = append(ids, id) + } + return +} + +// FollowingIDs returns the following ids in the mutation. +func (m *UserMutation) FollowingIDs() (ids []string) { + for id := range m.following { + ids = append(ids, id) + } + return +} + +// ResetFollowing reset all changes of the following edge. +func (m *UserMutation) ResetFollowing() { + m.following = nil + m.removedfollowing = nil +} + +// SetTeamID sets the team edge to Pet by id. +func (m *UserMutation) SetTeamID(id string) { + m.team = &id +} + +// ClearTeam clears the team edge to Pet. +func (m *UserMutation) ClearTeam() { + m.clearedteam = true +} + +// TeamCleared returns if the edge team was cleared. +func (m *UserMutation) TeamCleared() bool { + return m.clearedteam +} + +// TeamID returns the team id in the mutation. +func (m *UserMutation) TeamID() (id string, exists bool) { + if m.team != nil { + return *m.team, true + } + return +} + +// TeamIDs returns the team ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// TeamID instead. It exists only for internal usage by the builders. +func (m *UserMutation) TeamIDs() (ids []string) { + if id := m.team; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetTeam reset all changes of the team edge. +func (m *UserMutation) ResetTeam() { + m.team = nil + m.clearedteam = false +} + +// SetSpouseID sets the spouse edge to User by id. +func (m *UserMutation) SetSpouseID(id string) { + m.spouse = &id +} + +// ClearSpouse clears the spouse edge to User. +func (m *UserMutation) ClearSpouse() { + m.clearedspouse = true +} + +// SpouseCleared returns if the edge spouse was cleared. +func (m *UserMutation) SpouseCleared() bool { + return m.clearedspouse +} + +// SpouseID returns the spouse id in the mutation. +func (m *UserMutation) SpouseID() (id string, exists bool) { + if m.spouse != nil { + return *m.spouse, true + } + return +} + +// SpouseIDs returns the spouse ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// SpouseID instead. It exists only for internal usage by the builders. +func (m *UserMutation) SpouseIDs() (ids []string) { + if id := m.spouse; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSpouse reset all changes of the spouse edge. +func (m *UserMutation) ResetSpouse() { + m.spouse = nil + m.clearedspouse = false +} + +// AddChildIDs adds the children edge to User by ids. +func (m *UserMutation) AddChildIDs(ids ...string) { + if m.children == nil { + m.children = make(map[string]struct{}) + } + for i := range ids { + m.children[ids[i]] = struct{}{} + } +} + +// RemoveChildIDs removes the children edge to User by ids. +func (m *UserMutation) RemoveChildIDs(ids ...string) { + if m.removedchildren == nil { + m.removedchildren = make(map[string]struct{}) + } + for i := range ids { + m.removedchildren[ids[i]] = struct{}{} + } +} + +// RemovedChildren returns the removed ids of children. +func (m *UserMutation) RemovedChildrenIDs() (ids []string) { + for id := range m.removedchildren { + ids = append(ids, id) + } + return +} + +// ChildrenIDs returns the children ids in the mutation. +func (m *UserMutation) ChildrenIDs() (ids []string) { + for id := range m.children { + ids = append(ids, id) + } + return +} + +// ResetChildren reset all changes of the children edge. +func (m *UserMutation) ResetChildren() { + m.children = nil + m.removedchildren = nil +} + +// SetParentID sets the parent edge to User by id. +func (m *UserMutation) SetParentID(id string) { + m.parent = &id +} + +// ClearParent clears the parent edge to User. +func (m *UserMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared returns if the edge parent was cleared. +func (m *UserMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the parent id in the mutation. +func (m *UserMutation) ParentID() (id string, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the parent ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *UserMutation) ParentIDs() (ids []string) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent reset all changes of the parent edge. +func (m *UserMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 8) + if m.optional_int != nil { + fields = append(fields, user.FieldOptionalInt) + } + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + if m.last != nil { + fields = append(fields, user.FieldLast) + } + if m.nickname != nil { + fields = append(fields, user.FieldNickname) + } + if m.phone != nil { + fields = append(fields, user.FieldPhone) + } + if m.password != nil { + fields = append(fields, user.FieldPassword) + } + if m.role != nil { + fields = append(fields, user.FieldRole) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldOptionalInt: + return m.OptionalInt() + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + case user.FieldLast: + return m.Last() + case user.FieldNickname: + return m.Nickname() + case user.FieldPhone: + return m.Phone() + case user.FieldPassword: + return m.Password() + case user.FieldRole: + return m.Role() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOptionalInt(v) + return nil + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case user.FieldLast: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLast(v) + return nil + case user.FieldNickname: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNickname(v) + return nil + case user.FieldPhone: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPhone(v) + return nil + case user.FieldPassword: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPassword(v) + return nil + case user.FieldRole: + v, ok := value.(user.Role) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRole(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addoptional_int != nil { + fields = append(fields, user.FieldOptionalInt) + } + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldOptionalInt: + return m.AddedOptionalInt() + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldOptionalInt: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOptionalInt(v) + return nil + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[user.FieldOptionalInt] { + fields = append(fields, user.FieldOptionalInt) + } + if m.clearedFields[user.FieldNickname] { + fields = append(fields, user.FieldNickname) + } + if m.clearedFields[user.FieldPhone] { + fields = append(fields, user.FieldPhone) + } + if m.clearedFields[user.FieldPassword] { + fields = append(fields, user.FieldPassword) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + switch name { + case user.FieldOptionalInt: + m.ClearOptionalInt() + return nil + case user.FieldNickname: + m.ClearNickname() + return nil + case user.FieldPhone: + m.ClearPhone() + return nil + case user.FieldPassword: + m.ClearPassword() + return nil + } + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldOptionalInt: + m.ResetOptionalInt() + return nil + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + case user.FieldLast: + m.ResetLast() + return nil + case user.FieldNickname: + m.ResetNickname() + return nil + case user.FieldPhone: + m.ResetPhone() + return nil + case user.FieldPassword: + m.ResetPassword() + return nil + case user.FieldRole: + m.ResetRole() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 11) + if m.card != nil { + edges = append(edges, user.EdgeCard) + } + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + if m.files != nil { + edges = append(edges, user.EdgeFiles) + } + if m.groups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.friends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.followers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.following != nil { + edges = append(edges, user.EdgeFollowing) + } + if m.team != nil { + edges = append(edges, user.EdgeTeam) + } + if m.spouse != nil { + edges = append(edges, user.EdgeSpouse) + } + if m.children != nil { + edges = append(edges, user.EdgeChildren) + } + if m.parent != nil { + edges = append(edges, user.EdgeParent) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeCard: + if id := m.card; id != nil { + return []ent.Value{*id} + } + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.pets)) + for id := range m.pets { + ids = append(ids, id) + } + return ids + case user.EdgeFiles: + ids := make([]ent.Value, 0, len(m.files)) + for id := range m.files { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.followers)) + for id := range m.followers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.following)) + for id := range m.following { + ids = append(ids, id) + } + return ids + case user.EdgeTeam: + if id := m.team; id != nil { + return []ent.Value{*id} + } + case user.EdgeSpouse: + if id := m.spouse; id != nil { + return []ent.Value{*id} + } + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.children)) + for id := range m.children { + ids = append(ids, id) + } + return ids + case user.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 11) + if m.removedpets != nil { + edges = append(edges, user.EdgePets) + } + if m.removedfiles != nil { + edges = append(edges, user.EdgeFiles) + } + if m.removedgroups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.removedfriends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.removedfollowers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.removedfollowing != nil { + edges = append(edges, user.EdgeFollowing) + } + if m.removedchildren != nil { + edges = append(edges, user.EdgeChildren) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.removedpets)) + for id := range m.removedpets { + ids = append(ids, id) + } + return ids + case user.EdgeFiles: + ids := make([]ent.Value, 0, len(m.removedfiles)) + for id := range m.removedfiles { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.removedfollowers)) + for id := range m.removedfollowers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.removedfollowing)) + for id := range m.removedfollowing { + ids = append(ids, id) + } + return ids + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.removedchildren)) + for id := range m.removedchildren { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 11) + if m.clearedcard { + edges = append(edges, user.EdgeCard) + } + if m.clearedteam { + edges = append(edges, user.EdgeTeam) + } + if m.clearedspouse { + edges = append(edges, user.EdgeSpouse) + } + if m.clearedparent { + edges = append(edges, user.EdgeParent) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeCard: + return m.clearedcard + case user.EdgeTeam: + return m.clearedteam + case user.EdgeSpouse: + return m.clearedspouse + case user.EdgeParent: + return m.clearedparent + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeCard: + m.ClearCard() + return nil + case user.EdgeTeam: + m.ClearTeam() + return nil + case user.EdgeSpouse: + m.ClearSpouse() + return nil + case user.EdgeParent: + m.ClearParent() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeCard: + m.ResetCard() + return nil + case user.EdgePets: + m.ResetPets() + return nil + case user.EdgeFiles: + m.ResetFiles() + return nil + case user.EdgeGroups: + m.ResetGroups() + return nil + case user.EdgeFriends: + m.ResetFriends() + return nil + case user.EdgeFollowers: + m.ResetFollowers() + return nil + case user.EdgeFollowing: + m.ResetFollowing() + return nil + case user.EdgeTeam: + m.ResetTeam() + return nil + case user.EdgeSpouse: + m.ResetSpouse() + return nil + case user.EdgeChildren: + m.ResetChildren() + return nil + case user.EdgeParent: + m.ResetParent() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/gremlin/ent/node/node.go b/entc/integration/gremlin/ent/node/node.go index 19026da3e..666b7faf5 100644 --- a/entc/integration/gremlin/ent/node/node.go +++ b/entc/integration/gremlin/ent/node/node.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the node type in the database. Label = "node" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldValue holds the string denoting the value vertex property in the database. + FieldID = "id" // FieldValue holds the string denoting the value vertex property in the database. FieldValue = "value" + // EdgePrev holds the string denoting the prev edge name in mutations. + EdgePrev = "prev" + // EdgeNext holds the string denoting the next edge name in mutations. + EdgeNext = "next" + // PrevInverseLabel holds the string label denoting the prev inverse edge type in the database. PrevInverseLabel = "node_next" // NextLabel holds the string label denoting the next edge type in the database. diff --git a/entc/integration/gremlin/ent/node_create.go b/entc/integration/gremlin/ent/node_create.go index 9a53f3711..c93732d3c 100644 --- a/entc/integration/gremlin/ent/node_create.go +++ b/entc/integration/gremlin/ent/node_create.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -21,14 +21,13 @@ import ( // NodeCreate is the builder for creating a Node entity. type NodeCreate struct { config - value *int - prev map[string]struct{} - next map[string]struct{} + mutation *NodeMutation + hooks []Hook } // SetValue sets the value field. func (nc *NodeCreate) SetValue(i int) *NodeCreate { - nc.value = &i + nc.mutation.SetValue(i) return nc } @@ -42,10 +41,7 @@ func (nc *NodeCreate) SetNillableValue(i *int) *NodeCreate { // SetPrevID sets the prev edge to Node by id. func (nc *NodeCreate) SetPrevID(id string) *NodeCreate { - if nc.prev == nil { - nc.prev = make(map[string]struct{}) - } - nc.prev[id] = struct{}{} + nc.mutation.SetPrevID(id) return nc } @@ -64,10 +60,7 @@ func (nc *NodeCreate) SetPrev(n *Node) *NodeCreate { // SetNextID sets the next edge to Node by id. func (nc *NodeCreate) SetNextID(id string) *NodeCreate { - if nc.next == nil { - nc.next = make(map[string]struct{}) - } - nc.next[id] = struct{}{} + nc.mutation.SetNextID(id) return nc } @@ -86,13 +79,30 @@ func (nc *NodeCreate) SetNext(n *Node) *NodeCreate { // Save creates the Node in the database. func (nc *NodeCreate) Save(ctx context.Context) (*Node, error) { - if len(nc.prev) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"prev\"") + var ( + err error + node *Node + ) + if len(nc.hooks) == 0 { + node, err = nc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nc.mutation = mutation + node, err = nc.gremlinSave(ctx) + return node, err + }) + for i := len(nc.hooks); i > 0; i-- { + mut = nc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nc.mutation); err != nil { + return nil, err + } } - if len(nc.next) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nc.gremlinSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -127,17 +137,17 @@ func (nc *NodeCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 2) v := g.AddV(node.Label) - if nc.value != nil { - v.Property(dsl.Single, node.FieldValue, *nc.value) + if value, ok := nc.mutation.Value(); ok { + v.Property(dsl.Single, node.FieldValue, value) } - for id := range nc.prev { + for _, id := range nc.mutation.PrevIDs() { v.AddE(node.NextLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(node.NextLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(node.Label, node.NextLabel, id)), }) } - for id := range nc.next { + for _, id := range nc.mutation.NextIDs() { v.AddE(node.NextLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(node.NextLabel).InV().HasID(id).Count(), diff --git a/entc/integration/gremlin/ent/node_delete.go b/entc/integration/gremlin/ent/node_delete.go index ee86662e1..8e941dc3f 100644 --- a/entc/integration/gremlin/ent/node_delete.go +++ b/entc/integration/gremlin/ent/node_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // NodeDelete is the builder for deleting a Node entity. type NodeDelete struct { config + hooks []Hook + mutation *NodeMutation predicates []predicate.Node } @@ -31,7 +34,30 @@ func (nd *NodeDelete) Where(ps ...predicate.Node) *NodeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (nd *NodeDelete) Exec(ctx context.Context) (int, error) { - return nd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(nd.hooks) == 0 { + affected, err = nd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nd.mutation = mutation + affected, err = nd.gremlinExec(ctx) + return affected, err + }) + for i := len(nd.hooks); i > 0; i-- { + mut = nd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/node_update.go b/entc/integration/gremlin/ent/node_update.go index 39edc1486..76f4b9e8d 100644 --- a/entc/integration/gremlin/ent/node_update.go +++ b/entc/integration/gremlin/ent/node_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -22,14 +22,9 @@ import ( // NodeUpdate is the builder for updating Node entities. type NodeUpdate struct { config - value *int - addvalue *int - clearvalue bool - prev map[string]struct{} - next map[string]struct{} - clearedPrev bool - clearedNext bool - predicates []predicate.Node + hooks []Hook + mutation *NodeMutation + predicates []predicate.Node } // Where adds a new predicate for the builder. @@ -40,8 +35,8 @@ func (nu *NodeUpdate) Where(ps ...predicate.Node) *NodeUpdate { // SetValue sets the value field. func (nu *NodeUpdate) SetValue(i int) *NodeUpdate { - nu.value = &i - nu.addvalue = nil + nu.mutation.ResetValue() + nu.mutation.SetValue(i) return nu } @@ -55,27 +50,19 @@ func (nu *NodeUpdate) SetNillableValue(i *int) *NodeUpdate { // AddValue adds i to value. func (nu *NodeUpdate) AddValue(i int) *NodeUpdate { - if nu.addvalue == nil { - nu.addvalue = &i - } else { - *nu.addvalue += i - } + nu.mutation.AddValue(i) return nu } // ClearValue clears the value of value. func (nu *NodeUpdate) ClearValue() *NodeUpdate { - nu.value = nil - nu.clearvalue = true + nu.mutation.ClearValue() return nu } // SetPrevID sets the prev edge to Node by id. func (nu *NodeUpdate) SetPrevID(id string) *NodeUpdate { - if nu.prev == nil { - nu.prev = make(map[string]struct{}) - } - nu.prev[id] = struct{}{} + nu.mutation.SetPrevID(id) return nu } @@ -94,10 +81,7 @@ func (nu *NodeUpdate) SetPrev(n *Node) *NodeUpdate { // SetNextID sets the next edge to Node by id. func (nu *NodeUpdate) SetNextID(id string) *NodeUpdate { - if nu.next == nil { - nu.next = make(map[string]struct{}) - } - nu.next[id] = struct{}{} + nu.mutation.SetNextID(id) return nu } @@ -116,25 +100,43 @@ func (nu *NodeUpdate) SetNext(n *Node) *NodeUpdate { // ClearPrev clears the prev edge to Node. func (nu *NodeUpdate) ClearPrev() *NodeUpdate { - nu.clearedPrev = true + nu.mutation.ClearPrev() return nu } // ClearNext clears the next edge to Node. func (nu *NodeUpdate) ClearNext() *NodeUpdate { - nu.clearedNext = true + nu.mutation.ClearNext() return nu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (nu *NodeUpdate) Save(ctx context.Context) (int, error) { - if len(nu.prev) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"prev\"") + + var ( + err error + affected int + ) + if len(nu.hooks) == 0 { + affected, err = nu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nu.mutation = mutation + affected, err = nu.gremlinSave(ctx) + return affected, err + }) + for i := len(nu.hooks); i > 0; i-- { + mut = nu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nu.mutation); err != nil { + return 0, err + } } - if len(nu.next) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nu.gremlinSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -187,35 +189,35 @@ func (nu *NodeUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := nu.value; value != nil { - v.Property(dsl.Single, node.FieldValue, *value) + if value, ok := nu.mutation.Value(); ok { + v.Property(dsl.Single, node.FieldValue, value) } - if value := nu.addvalue; value != nil { - v.Property(dsl.Single, node.FieldValue, __.Union(__.Values(node.FieldValue), __.Constant(*value)).Sum()) + if value, ok := nu.mutation.AddedValue(); ok { + v.Property(dsl.Single, node.FieldValue, __.Union(__.Values(node.FieldValue), __.Constant(value)).Sum()) } var properties []interface{} - if nu.clearvalue { + if nu.mutation.ValueCleared() { properties = append(properties, node.FieldValue) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if nu.clearedPrev { + if nu.mutation.PrevCleared() { tr := rv.Clone().InE(node.NextLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range nu.prev { + for _, id := range nu.mutation.PrevIDs() { v.AddE(node.NextLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(node.NextLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(node.Label, node.NextLabel, id)), }) } - if nu.clearedNext { + if nu.mutation.NextCleared() { tr := rv.Clone().OutE(node.NextLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range nu.next { + for _, id := range nu.mutation.NextIDs() { v.AddE(node.NextLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(node.NextLabel).InV().HasID(id).Count(), @@ -240,20 +242,14 @@ func (nu *NodeUpdate) gremlin() *dsl.Traversal { // NodeUpdateOne is the builder for updating a single Node entity. type NodeUpdateOne struct { config - id string - value *int - addvalue *int - clearvalue bool - prev map[string]struct{} - next map[string]struct{} - clearedPrev bool - clearedNext bool + hooks []Hook + mutation *NodeMutation } // SetValue sets the value field. func (nuo *NodeUpdateOne) SetValue(i int) *NodeUpdateOne { - nuo.value = &i - nuo.addvalue = nil + nuo.mutation.ResetValue() + nuo.mutation.SetValue(i) return nuo } @@ -267,27 +263,19 @@ func (nuo *NodeUpdateOne) SetNillableValue(i *int) *NodeUpdateOne { // AddValue adds i to value. func (nuo *NodeUpdateOne) AddValue(i int) *NodeUpdateOne { - if nuo.addvalue == nil { - nuo.addvalue = &i - } else { - *nuo.addvalue += i - } + nuo.mutation.AddValue(i) return nuo } // ClearValue clears the value of value. func (nuo *NodeUpdateOne) ClearValue() *NodeUpdateOne { - nuo.value = nil - nuo.clearvalue = true + nuo.mutation.ClearValue() return nuo } // SetPrevID sets the prev edge to Node by id. func (nuo *NodeUpdateOne) SetPrevID(id string) *NodeUpdateOne { - if nuo.prev == nil { - nuo.prev = make(map[string]struct{}) - } - nuo.prev[id] = struct{}{} + nuo.mutation.SetPrevID(id) return nuo } @@ -306,10 +294,7 @@ func (nuo *NodeUpdateOne) SetPrev(n *Node) *NodeUpdateOne { // SetNextID sets the next edge to Node by id. func (nuo *NodeUpdateOne) SetNextID(id string) *NodeUpdateOne { - if nuo.next == nil { - nuo.next = make(map[string]struct{}) - } - nuo.next[id] = struct{}{} + nuo.mutation.SetNextID(id) return nuo } @@ -328,25 +313,43 @@ func (nuo *NodeUpdateOne) SetNext(n *Node) *NodeUpdateOne { // ClearPrev clears the prev edge to Node. func (nuo *NodeUpdateOne) ClearPrev() *NodeUpdateOne { - nuo.clearedPrev = true + nuo.mutation.ClearPrev() return nuo } // ClearNext clears the next edge to Node. func (nuo *NodeUpdateOne) ClearNext() *NodeUpdateOne { - nuo.clearedNext = true + nuo.mutation.ClearNext() return nuo } // Save executes the query and returns the updated entity. func (nuo *NodeUpdateOne) Save(ctx context.Context) (*Node, error) { - if len(nuo.prev) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"prev\"") + + var ( + err error + node *Node + ) + if len(nuo.hooks) == 0 { + node, err = nuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nuo.mutation = mutation + node, err = nuo.gremlinSave(ctx) + return node, err + }) + for i := len(nuo.hooks); i > 0; i-- { + mut = nuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nuo.mutation); err != nil { + return nil, err + } } - if len(nuo.next) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nuo.gremlinSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -373,7 +376,11 @@ func (nuo *NodeUpdateOne) ExecX(ctx context.Context) { func (nuo *NodeUpdateOne) gremlinSave(ctx context.Context) (*Node, error) { res := &gremlin.Response{} - query, bindings := nuo.gremlin(nuo.id).Query() + id, ok := nuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Node.ID for update") + } + query, bindings := nuo.gremlin(id).Query() if err := nuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -400,35 +407,35 @@ func (nuo *NodeUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := nuo.value; value != nil { - v.Property(dsl.Single, node.FieldValue, *value) + if value, ok := nuo.mutation.Value(); ok { + v.Property(dsl.Single, node.FieldValue, value) } - if value := nuo.addvalue; value != nil { - v.Property(dsl.Single, node.FieldValue, __.Union(__.Values(node.FieldValue), __.Constant(*value)).Sum()) + if value, ok := nuo.mutation.AddedValue(); ok { + v.Property(dsl.Single, node.FieldValue, __.Union(__.Values(node.FieldValue), __.Constant(value)).Sum()) } var properties []interface{} - if nuo.clearvalue { + if nuo.mutation.ValueCleared() { properties = append(properties, node.FieldValue) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if nuo.clearedPrev { + if nuo.mutation.PrevCleared() { tr := rv.Clone().InE(node.NextLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range nuo.prev { + for _, id := range nuo.mutation.PrevIDs() { v.AddE(node.NextLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(node.NextLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(node.Label, node.NextLabel, id)), }) } - if nuo.clearedNext { + if nuo.mutation.NextCleared() { tr := rv.Clone().OutE(node.NextLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range nuo.next { + for _, id := range nuo.mutation.NextIDs() { v.AddE(node.NextLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(node.NextLabel).InV().HasID(id).Count(), diff --git a/entc/integration/gremlin/ent/pet/pet.go b/entc/integration/gremlin/ent/pet/pet.go index 7d55c4f2b..7b74e03ca 100644 --- a/entc/integration/gremlin/ent/pet/pet.go +++ b/entc/integration/gremlin/ent/pet/pet.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the pet type in the database. Label = "pet" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeTeam holds the string denoting the team edge name in mutations. + EdgeTeam = "team" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // TeamInverseLabel holds the string label denoting the team inverse edge type in the database. TeamInverseLabel = "user_team" // OwnerInverseLabel holds the string label denoting the owner inverse edge type in the database. diff --git a/entc/integration/gremlin/ent/pet_create.go b/entc/integration/gremlin/ent/pet_create.go index b1e001a31..d864c5dbb 100644 --- a/entc/integration/gremlin/ent/pet_create.go +++ b/entc/integration/gremlin/ent/pet_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -22,23 +23,19 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - name *string - team map[string]struct{} - owner map[string]struct{} + mutation *PetMutation + hooks []Hook } // SetName sets the name field. func (pc *PetCreate) SetName(s string) *PetCreate { - pc.name = &s + pc.mutation.SetName(s) return pc } // SetTeamID sets the team edge to User by id. func (pc *PetCreate) SetTeamID(id string) *PetCreate { - if pc.team == nil { - pc.team = make(map[string]struct{}) - } - pc.team[id] = struct{}{} + pc.mutation.SetTeamID(id) return pc } @@ -57,10 +54,7 @@ func (pc *PetCreate) SetTeam(u *User) *PetCreate { // SetOwnerID sets the owner edge to User by id. func (pc *PetCreate) SetOwnerID(id string) *PetCreate { - if pc.owner == nil { - pc.owner = make(map[string]struct{}) - } - pc.owner[id] = struct{}{} + pc.mutation.SetOwnerID(id) return pc } @@ -79,16 +73,33 @@ func (pc *PetCreate) SetOwner(u *User) *PetCreate { // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - if pc.name == nil { + if _, ok := pc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(pc.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.gremlinSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } } - if len(pc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - return pc.gremlinSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -123,17 +134,17 @@ func (pc *PetCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 1) v := g.AddV(pet.Label) - if pc.name != nil { - v.Property(dsl.Single, pet.FieldName, *pc.name) + if value, ok := pc.mutation.Name(); ok { + v.Property(dsl.Single, pet.FieldName, value) } - for id := range pc.team { + for _, id := range pc.mutation.TeamIDs() { v.AddE(user.TeamLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.TeamLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(pet.Label, user.TeamLabel, id)), }) } - for id := range pc.owner { + for _, id := range pc.mutation.OwnerIDs() { v.AddE(user.PetsLabel).From(g.V(id)).InV() } if len(constraints) == 0 { diff --git a/entc/integration/gremlin/ent/pet_delete.go b/entc/integration/gremlin/ent/pet_delete.go index 92d65f0b1..35b8253ca 100644 --- a/entc/integration/gremlin/ent/pet_delete.go +++ b/entc/integration/gremlin/ent/pet_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -31,7 +34,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.gremlinExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/pet_update.go b/entc/integration/gremlin/ent/pet_update.go index f063d3442..7bd854d32 100644 --- a/entc/integration/gremlin/ent/pet_update.go +++ b/entc/integration/gremlin/ent/pet_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -23,12 +23,9 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - name *string - team map[string]struct{} - owner map[string]struct{} - clearedTeam bool - clearedOwner bool - predicates []predicate.Pet + hooks []Hook + mutation *PetMutation + predicates []predicate.Pet } // Where adds a new predicate for the builder. @@ -39,16 +36,13 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // SetName sets the name field. func (pu *PetUpdate) SetName(s string) *PetUpdate { - pu.name = &s + pu.mutation.SetName(s) return pu } // SetTeamID sets the team edge to User by id. func (pu *PetUpdate) SetTeamID(id string) *PetUpdate { - if pu.team == nil { - pu.team = make(map[string]struct{}) - } - pu.team[id] = struct{}{} + pu.mutation.SetTeamID(id) return pu } @@ -67,10 +61,7 @@ func (pu *PetUpdate) SetTeam(u *User) *PetUpdate { // SetOwnerID sets the owner edge to User by id. func (pu *PetUpdate) SetOwnerID(id string) *PetUpdate { - if pu.owner == nil { - pu.owner = make(map[string]struct{}) - } - pu.owner[id] = struct{}{} + pu.mutation.SetOwnerID(id) return pu } @@ -89,25 +80,43 @@ func (pu *PetUpdate) SetOwner(u *User) *PetUpdate { // ClearTeam clears the team edge to User. func (pu *PetUpdate) ClearTeam() *PetUpdate { - pu.clearedTeam = true + pu.mutation.ClearTeam() return pu } // ClearOwner clears the owner edge to User. func (pu *PetUpdate) ClearOwner() *PetUpdate { - pu.clearedOwner = true + pu.mutation.ClearOwner() return pu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - if len(pu.team) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"team\"") + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.gremlinSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } } - if len(pu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - return pu.gremlinSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -160,25 +169,25 @@ func (pu *PetUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := pu.name; value != nil { - v.Property(dsl.Single, pet.FieldName, *value) + if value, ok := pu.mutation.Name(); ok { + v.Property(dsl.Single, pet.FieldName, value) } - if pu.clearedTeam { + if pu.mutation.TeamCleared() { tr := rv.Clone().InE(user.TeamLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range pu.team { + for _, id := range pu.mutation.TeamIDs() { v.AddE(user.TeamLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.TeamLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(pet.Label, user.TeamLabel, id)), }) } - if pu.clearedOwner { + if pu.mutation.OwnerCleared() { tr := rv.Clone().InE(user.PetsLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range pu.owner { + for _, id := range pu.mutation.OwnerIDs() { v.AddE(user.PetsLabel).From(g.V(id)).InV() } v.Count() @@ -199,26 +208,19 @@ func (pu *PetUpdate) gremlin() *dsl.Traversal { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id string - name *string - team map[string]struct{} - owner map[string]struct{} - clearedTeam bool - clearedOwner bool + hooks []Hook + mutation *PetMutation } // SetName sets the name field. func (puo *PetUpdateOne) SetName(s string) *PetUpdateOne { - puo.name = &s + puo.mutation.SetName(s) return puo } // SetTeamID sets the team edge to User by id. func (puo *PetUpdateOne) SetTeamID(id string) *PetUpdateOne { - if puo.team == nil { - puo.team = make(map[string]struct{}) - } - puo.team[id] = struct{}{} + puo.mutation.SetTeamID(id) return puo } @@ -237,10 +239,7 @@ func (puo *PetUpdateOne) SetTeam(u *User) *PetUpdateOne { // SetOwnerID sets the owner edge to User by id. func (puo *PetUpdateOne) SetOwnerID(id string) *PetUpdateOne { - if puo.owner == nil { - puo.owner = make(map[string]struct{}) - } - puo.owner[id] = struct{}{} + puo.mutation.SetOwnerID(id) return puo } @@ -259,25 +258,43 @@ func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne { // ClearTeam clears the team edge to User. func (puo *PetUpdateOne) ClearTeam() *PetUpdateOne { - puo.clearedTeam = true + puo.mutation.ClearTeam() return puo } // ClearOwner clears the owner edge to User. func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne { - puo.clearedOwner = true + puo.mutation.ClearOwner() return puo } // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - if len(puo.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") + + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.gremlinSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } } - if len(puo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - return puo.gremlinSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -304,7 +321,11 @@ func (puo *PetUpdateOne) ExecX(ctx context.Context) { func (puo *PetUpdateOne) gremlinSave(ctx context.Context) (*Pet, error) { res := &gremlin.Response{} - query, bindings := puo.gremlin(puo.id).Query() + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + query, bindings := puo.gremlin(id).Query() if err := puo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -331,25 +352,25 @@ func (puo *PetUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := puo.name; value != nil { - v.Property(dsl.Single, pet.FieldName, *value) + if value, ok := puo.mutation.Name(); ok { + v.Property(dsl.Single, pet.FieldName, value) } - if puo.clearedTeam { + if puo.mutation.TeamCleared() { tr := rv.Clone().InE(user.TeamLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range puo.team { + for _, id := range puo.mutation.TeamIDs() { v.AddE(user.TeamLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.TeamLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(pet.Label, user.TeamLabel, id)), }) } - if puo.clearedOwner { + if puo.mutation.OwnerCleared() { tr := rv.Clone().InE(user.PetsLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range puo.owner { + for _, id := range puo.mutation.OwnerIDs() { v.AddE(user.PetsLabel).From(g.V(id)).InV() } v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/privacy/privacy.go b/entc/integration/gremlin/ent/privacy/privacy.go new file mode 100644 index 000000000..837cecaff --- /dev/null +++ b/entc/integration/gremlin/ent/privacy/privacy.go @@ -0,0 +1,435 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/gremlin/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CardReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CardReadRuleFunc func(context.Context, *ent.Card) error + +// EvalRead calls f(ctx, v). +func (f CardReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Card); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Card", v) +} + +// The CardWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CardWriteRuleFunc func(context.Context, *ent.CardMutation) error + +// EvalWrite calls f(ctx, m). +func (f CardWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CardMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CardMutation", m) +} + +// The CommentReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CommentReadRuleFunc func(context.Context, *ent.Comment) error + +// EvalRead calls f(ctx, v). +func (f CommentReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Comment); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Comment", v) +} + +// The CommentWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CommentWriteRuleFunc func(context.Context, *ent.CommentMutation) error + +// EvalWrite calls f(ctx, m). +func (f CommentWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CommentMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CommentMutation", m) +} + +// The FieldTypeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type FieldTypeReadRuleFunc func(context.Context, *ent.FieldType) error + +// EvalRead calls f(ctx, v). +func (f FieldTypeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.FieldType); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.FieldType", v) +} + +// The FieldTypeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type FieldTypeWriteRuleFunc func(context.Context, *ent.FieldTypeMutation) error + +// EvalWrite calls f(ctx, m). +func (f FieldTypeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.FieldTypeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.FieldTypeMutation", m) +} + +// The FileReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type FileReadRuleFunc func(context.Context, *ent.File) error + +// EvalRead calls f(ctx, v). +func (f FileReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.File); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.File", v) +} + +// The FileWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type FileWriteRuleFunc func(context.Context, *ent.FileMutation) error + +// EvalWrite calls f(ctx, m). +func (f FileWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.FileMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.FileMutation", m) +} + +// The FileTypeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type FileTypeReadRuleFunc func(context.Context, *ent.FileType) error + +// EvalRead calls f(ctx, v). +func (f FileTypeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.FileType); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.FileType", v) +} + +// The FileTypeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type FileTypeWriteRuleFunc func(context.Context, *ent.FileTypeMutation) error + +// EvalWrite calls f(ctx, m). +func (f FileTypeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.FileTypeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.FileTypeMutation", m) +} + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The GroupInfoReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupInfoReadRuleFunc func(context.Context, *ent.GroupInfo) error + +// EvalRead calls f(ctx, v). +func (f GroupInfoReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.GroupInfo); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.GroupInfo", v) +} + +// The GroupInfoWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupInfoWriteRuleFunc func(context.Context, *ent.GroupInfoMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupInfoWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupInfoMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupInfoMutation", m) +} + +// The ItemReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type ItemReadRuleFunc func(context.Context, *ent.Item) error + +// EvalRead calls f(ctx, v). +func (f ItemReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Item); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Item", v) +} + +// The ItemWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type ItemWriteRuleFunc func(context.Context, *ent.ItemMutation) error + +// EvalWrite calls f(ctx, m). +func (f ItemWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.ItemMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.ItemMutation", m) +} + +// The NodeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type NodeReadRuleFunc func(context.Context, *ent.Node) error + +// EvalRead calls f(ctx, v). +func (f NodeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Node); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Node", v) +} + +// The NodeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type NodeWriteRuleFunc func(context.Context, *ent.NodeMutation) error + +// EvalWrite calls f(ctx, m). +func (f NodeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.NodeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.NodeMutation", m) +} + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The SpecReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type SpecReadRuleFunc func(context.Context, *ent.Spec) error + +// EvalRead calls f(ctx, v). +func (f SpecReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Spec); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Spec", v) +} + +// The SpecWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type SpecWriteRuleFunc func(context.Context, *ent.SpecMutation) error + +// EvalWrite calls f(ctx, m). +func (f SpecWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.SpecMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.SpecMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/gremlin/ent/runtime.go b/entc/integration/gremlin/ent/runtime.go new file mode 100644 index 000000000..bf5baac5d --- /dev/null +++ b/entc/integration/gremlin/ent/runtime.go @@ -0,0 +1,131 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "time" + + "github.com/facebookincubator/ent/entc/integration/ent/schema" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/card" + + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/fieldtype" + + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/file" + + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/group" + + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/groupinfo" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/entc/integration/gremlin/ent/user" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + cardMixin := schema.Card{}.Mixin() + cardMixinFields := [...][]ent.Field{ + cardMixin[0].Fields(), + } + cardFields := schema.Card{}.Fields() + // cardDescCreateTime is the schema descriptor for create_time field. + cardDescCreateTime := cardMixinFields[0][0].Descriptor() + // card.DefaultCreateTime holds the default value on creation for the create_time field. + card.DefaultCreateTime = cardDescCreateTime.Default.(func() time.Time) + // cardDescUpdateTime is the schema descriptor for update_time field. + cardDescUpdateTime := cardMixinFields[0][1].Descriptor() + // card.DefaultUpdateTime holds the default value on creation for the update_time field. + card.DefaultUpdateTime = cardDescUpdateTime.Default.(func() time.Time) + // card.UpdateDefaultUpdateTime holds the default value on update for the update_time field. + card.UpdateDefaultUpdateTime = cardDescUpdateTime.UpdateDefault.(func() time.Time) + // cardDescNumber is the schema descriptor for number field. + cardDescNumber := cardFields[0].Descriptor() + // card.NumberValidator is a validator for the "number" field. It is called by the builders before save. + card.NumberValidator = cardDescNumber.Validators[0].(func(string) error) + // cardDescName is the schema descriptor for name field. + cardDescName := cardFields[1].Descriptor() + // card.NameValidator is a validator for the "name" field. It is called by the builders before save. + card.NameValidator = cardDescName.Validators[0].(func(string) error) + fieldtypeFields := schema.FieldType{}.Fields() + // fieldtypeDescValidateOptionalInt32 is the schema descriptor for validate_optional_int32 field. + fieldtypeDescValidateOptionalInt32 := fieldtypeFields[15].Descriptor() + // fieldtype.ValidateOptionalInt32Validator is a validator for the "validate_optional_int32" field. It is called by the builders before save. + fieldtype.ValidateOptionalInt32Validator = fieldtypeDescValidateOptionalInt32.Validators[0].(func(int32) error) + fileFields := schema.File{}.Fields() + // fileDescSize is the schema descriptor for size field. + fileDescSize := fileFields[0].Descriptor() + // file.DefaultSize holds the default value on creation for the size field. + file.DefaultSize = fileDescSize.Default.(int) + // file.SizeValidator is a validator for the "size" field. It is called by the builders before save. + file.SizeValidator = fileDescSize.Validators[0].(func(int) error) + groupFields := schema.Group{}.Fields() + // groupDescActive is the schema descriptor for active field. + groupDescActive := groupFields[0].Descriptor() + // group.DefaultActive holds the default value on creation for the active field. + group.DefaultActive = groupDescActive.Default.(bool) + // groupDescType is the schema descriptor for type field. + groupDescType := groupFields[2].Descriptor() + // group.TypeValidator is a validator for the "type" field. It is called by the builders before save. + group.TypeValidator = func() func(string) error { + validators := groupDescType.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(_type string) error { + for _, fn := range fns { + if err := fn(_type); err != nil { + return err + } + } + return nil + } + }() + // groupDescMaxUsers is the schema descriptor for max_users field. + groupDescMaxUsers := groupFields[3].Descriptor() + // group.DefaultMaxUsers holds the default value on creation for the max_users field. + group.DefaultMaxUsers = groupDescMaxUsers.Default.(int) + // group.MaxUsersValidator is a validator for the "max_users" field. It is called by the builders before save. + group.MaxUsersValidator = groupDescMaxUsers.Validators[0].(func(int) error) + // groupDescName is the schema descriptor for name field. + groupDescName := groupFields[4].Descriptor() + // group.NameValidator is a validator for the "name" field. It is called by the builders before save. + group.NameValidator = func() func(string) error { + validators := groupDescName.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(name string) error { + for _, fn := range fns { + if err := fn(name); err != nil { + return err + } + } + return nil + } + }() + groupinfoFields := schema.GroupInfo{}.Fields() + // groupinfoDescMaxUsers is the schema descriptor for max_users field. + groupinfoDescMaxUsers := groupinfoFields[1].Descriptor() + // groupinfo.DefaultMaxUsers holds the default value on creation for the max_users field. + groupinfo.DefaultMaxUsers = groupinfoDescMaxUsers.Default.(int) + userMixin := schema.User{}.Mixin() + userMixinFields := [...][]ent.Field{ + userMixin[0].Fields(), + } + userFields := schema.User{}.Fields() + // userDescOptionalInt is the schema descriptor for optional_int field. + userDescOptionalInt := userMixinFields[0][0].Descriptor() + // user.OptionalIntValidator is a validator for the "optional_int" field. It is called by the builders before save. + user.OptionalIntValidator = userDescOptionalInt.Validators[0].(func(int) error) + // userDescLast is the schema descriptor for last field. + userDescLast := userFields[2].Descriptor() + // user.DefaultLast holds the default value on creation for the last field. + user.DefaultLast = userDescLast.Default.(string) +} diff --git a/entc/integration/gremlin/ent/runtime/runtime.go b/entc/integration/gremlin/ent/runtime/runtime.go new file mode 100644 index 000000000..9a41ecf7a --- /dev/null +++ b/entc/integration/gremlin/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/gremlin/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/gremlin/ent/spec/spec.go b/entc/integration/gremlin/ent/spec/spec.go index c87bf79c5..9d01bbb24 100644 --- a/entc/integration/gremlin/ent/spec/spec.go +++ b/entc/integration/gremlin/ent/spec/spec.go @@ -12,6 +12,9 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeCard holds the string denoting the card edge name in mutations. + EdgeCard = "card" + // CardLabel holds the string label denoting the card edge type in the database. CardLabel = "spec_card" ) diff --git a/entc/integration/gremlin/ent/spec_create.go b/entc/integration/gremlin/ent/spec_create.go index 692b0b7dc..40d372bea 100644 --- a/entc/integration/gremlin/ent/spec_create.go +++ b/entc/integration/gremlin/ent/spec_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -18,17 +19,13 @@ import ( // SpecCreate is the builder for creating a Spec entity. type SpecCreate struct { config - card map[string]struct{} + mutation *SpecMutation + hooks []Hook } // AddCardIDs adds the card edge to Card by ids. func (sc *SpecCreate) AddCardIDs(ids ...string) *SpecCreate { - if sc.card == nil { - sc.card = make(map[string]struct{}) - } - for i := range ids { - sc.card[ids[i]] = struct{}{} - } + sc.mutation.AddCardIDs(ids...) return sc } @@ -43,7 +40,30 @@ func (sc *SpecCreate) AddCard(c ...*Card) *SpecCreate { // Save creates the Spec in the database. func (sc *SpecCreate) Save(ctx context.Context) (*Spec, error) { - return sc.gremlinSave(ctx) + var ( + err error + node *Spec + ) + if len(sc.hooks) == 0 { + node, err = sc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + sc.mutation = mutation + node, err = sc.gremlinSave(ctx) + return node, err + }) + for i := len(sc.hooks); i > 0; i-- { + mut = sc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, sc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -73,7 +93,7 @@ func (sc *SpecCreate) gremlinSave(ctx context.Context) (*Spec, error) { func (sc *SpecCreate) gremlin() *dsl.Traversal { v := g.AddV(spec.Label) - for id := range sc.card { + for _, id := range sc.mutation.CardIDs() { v.AddE(spec.CardLabel).To(g.V(id)).OutV() } return v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/spec_delete.go b/entc/integration/gremlin/ent/spec_delete.go index 496c3a299..206351ee6 100644 --- a/entc/integration/gremlin/ent/spec_delete.go +++ b/entc/integration/gremlin/ent/spec_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // SpecDelete is the builder for deleting a Spec entity. type SpecDelete struct { config + hooks []Hook + mutation *SpecMutation predicates []predicate.Spec } @@ -31,7 +34,30 @@ func (sd *SpecDelete) Where(ps ...predicate.Spec) *SpecDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (sd *SpecDelete) Exec(ctx context.Context) (int, error) { - return sd.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(sd.hooks) == 0 { + affected, err = sd.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + sd.mutation = mutation + affected, err = sd.gremlinExec(ctx) + return affected, err + }) + for i := len(sd.hooks); i > 0; i-- { + mut = sd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, sd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/spec_update.go b/entc/integration/gremlin/ent/spec_update.go index 21323bb8f..58e8919a4 100644 --- a/entc/integration/gremlin/ent/spec_update.go +++ b/entc/integration/gremlin/ent/spec_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,9 +21,9 @@ import ( // SpecUpdate is the builder for updating Spec entities. type SpecUpdate struct { config - card map[string]struct{} - removedCard map[string]struct{} - predicates []predicate.Spec + hooks []Hook + mutation *SpecMutation + predicates []predicate.Spec } // Where adds a new predicate for the builder. @@ -33,12 +34,7 @@ func (su *SpecUpdate) Where(ps ...predicate.Spec) *SpecUpdate { // AddCardIDs adds the card edge to Card by ids. func (su *SpecUpdate) AddCardIDs(ids ...string) *SpecUpdate { - if su.card == nil { - su.card = make(map[string]struct{}) - } - for i := range ids { - su.card[ids[i]] = struct{}{} - } + su.mutation.AddCardIDs(ids...) return su } @@ -53,12 +49,7 @@ func (su *SpecUpdate) AddCard(c ...*Card) *SpecUpdate { // RemoveCardIDs removes the card edge to Card by ids. func (su *SpecUpdate) RemoveCardIDs(ids ...string) *SpecUpdate { - if su.removedCard == nil { - su.removedCard = make(map[string]struct{}) - } - for i := range ids { - su.removedCard[ids[i]] = struct{}{} - } + su.mutation.RemoveCardIDs(ids...) return su } @@ -73,7 +64,31 @@ func (su *SpecUpdate) RemoveCard(c ...*Card) *SpecUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (su *SpecUpdate) Save(ctx context.Context) (int, error) { - return su.gremlinSave(ctx) + + var ( + err error + affected int + ) + if len(su.hooks) == 0 { + affected, err = su.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + su.mutation = mutation + affected, err = su.gremlinSave(ctx) + return affected, err + }) + for i := len(su.hooks); i > 0; i-- { + mut = su.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, su.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -121,11 +136,11 @@ func (su *SpecUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - for id := range su.removedCard { + for _, id := range su.mutation.RemovedCardIDs() { tr := rv.Clone().OutE(spec.CardLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range su.card { + for _, id := range su.mutation.CardIDs() { v.AddE(spec.CardLabel).To(g.V(id)).OutV() } v.Count() @@ -136,19 +151,13 @@ func (su *SpecUpdate) gremlin() *dsl.Traversal { // SpecUpdateOne is the builder for updating a single Spec entity. type SpecUpdateOne struct { config - id string - card map[string]struct{} - removedCard map[string]struct{} + hooks []Hook + mutation *SpecMutation } // AddCardIDs adds the card edge to Card by ids. func (suo *SpecUpdateOne) AddCardIDs(ids ...string) *SpecUpdateOne { - if suo.card == nil { - suo.card = make(map[string]struct{}) - } - for i := range ids { - suo.card[ids[i]] = struct{}{} - } + suo.mutation.AddCardIDs(ids...) return suo } @@ -163,12 +172,7 @@ func (suo *SpecUpdateOne) AddCard(c ...*Card) *SpecUpdateOne { // RemoveCardIDs removes the card edge to Card by ids. func (suo *SpecUpdateOne) RemoveCardIDs(ids ...string) *SpecUpdateOne { - if suo.removedCard == nil { - suo.removedCard = make(map[string]struct{}) - } - for i := range ids { - suo.removedCard[ids[i]] = struct{}{} - } + suo.mutation.RemoveCardIDs(ids...) return suo } @@ -183,7 +187,31 @@ func (suo *SpecUpdateOne) RemoveCard(c ...*Card) *SpecUpdateOne { // Save executes the query and returns the updated entity. func (suo *SpecUpdateOne) Save(ctx context.Context) (*Spec, error) { - return suo.gremlinSave(ctx) + + var ( + err error + node *Spec + ) + if len(suo.hooks) == 0 { + node, err = suo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SpecMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + suo.mutation = mutation + node, err = suo.gremlinSave(ctx) + return node, err + }) + for i := len(suo.hooks); i > 0; i-- { + mut = suo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, suo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -210,7 +238,11 @@ func (suo *SpecUpdateOne) ExecX(ctx context.Context) { func (suo *SpecUpdateOne) gremlinSave(ctx context.Context) (*Spec, error) { res := &gremlin.Response{} - query, bindings := suo.gremlin(suo.id).Query() + id, ok := suo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Spec.ID for update") + } + query, bindings := suo.gremlin(id).Query() if err := suo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -232,11 +264,11 @@ func (suo *SpecUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - for id := range suo.removedCard { + for _, id := range suo.mutation.RemovedCardIDs() { tr := rv.Clone().OutE(spec.CardLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range suo.card { + for _, id := range suo.mutation.CardIDs() { v.AddE(spec.CardLabel).To(g.V(id)).OutV() } v.ValueMap(true) diff --git a/entc/integration/gremlin/ent/tx.go b/entc/integration/gremlin/ent/tx.go index c9b7ef60d..bf9096fd5 100644 --- a/entc/integration/gremlin/ent/tx.go +++ b/entc/integration/gremlin/ent/tx.go @@ -53,21 +53,24 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Card: NewCardClient(tx.config), - Comment: NewCommentClient(tx.config), - FieldType: NewFieldTypeClient(tx.config), - File: NewFileClient(tx.config), - FileType: NewFileTypeClient(tx.config), - Group: NewGroupClient(tx.config), - GroupInfo: NewGroupInfoClient(tx.config), - Item: NewItemClient(tx.config), - Node: NewNodeClient(tx.config), - Pet: NewPetClient(tx.config), - Spec: NewSpecClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Card = NewCardClient(tx.config) + tx.Comment = NewCommentClient(tx.config) + tx.FieldType = NewFieldTypeClient(tx.config) + tx.File = NewFileClient(tx.config) + tx.FileType = NewFileTypeClient(tx.config) + tx.Group = NewGroupClient(tx.config) + tx.GroupInfo = NewGroupInfoClient(tx.config) + tx.Item = NewItemClient(tx.config) + tx.Node = NewNodeClient(tx.config) + tx.Pet = NewPetClient(tx.config) + tx.Spec = NewSpecClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/gremlin/ent/user/user.go b/entc/integration/gremlin/ent/user/user.go index c8bd53a09..0928c80a0 100644 --- a/entc/integration/gremlin/ent/user/user.go +++ b/entc/integration/gremlin/ent/user/user.go @@ -8,32 +8,44 @@ package user import ( "fmt" - - "github.com/facebookincubator/ent" - "github.com/facebookincubator/ent/entc/integration/ent/schema" ) const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. - FieldOptionalInt = "optional_int" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" - // FieldLast holds the string denoting the last vertex property in the database. - FieldLast = "last" - // FieldNickname holds the string denoting the nickname vertex property in the database. - FieldNickname = "nickname" - // FieldPhone holds the string denoting the phone vertex property in the database. - FieldPhone = "phone" - // FieldPassword holds the string denoting the password vertex property in the database. - FieldPassword = "password" - // FieldRole holds the string denoting the role vertex property in the database. - FieldRole = "role" + FieldID = "id" // FieldOptionalInt holds the string denoting the optional_int vertex property in the database. + FieldOptionalInt = "optional_int" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldLast holds the string denoting the last vertex property in the database. + FieldLast = "last" // FieldNickname holds the string denoting the nickname vertex property in the database. + FieldNickname = "nickname" // FieldPhone holds the string denoting the phone vertex property in the database. + FieldPhone = "phone" // FieldPassword holds the string denoting the password vertex property in the database. + FieldPassword = "password" // FieldRole holds the string denoting the role vertex property in the database. + FieldRole = "role" + + // EdgeCard holds the string denoting the card edge name in mutations. + EdgeCard = "card" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" + // EdgeFiles holds the string denoting the files edge name in mutations. + EdgeFiles = "files" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // EdgeFollowers holds the string denoting the followers edge name in mutations. + EdgeFollowers = "followers" + // EdgeFollowing holds the string denoting the following edge name in mutations. + EdgeFollowing = "following" + // EdgeTeam holds the string denoting the team edge name in mutations. + EdgeTeam = "team" + // EdgeSpouse holds the string denoting the spouse edge name in mutations. + EdgeSpouse = "spouse" + // EdgeChildren holds the string denoting the children edge name in mutations. + EdgeChildren = "children" + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" // CardLabel holds the string label denoting the card edge type in the database. CardLabel = "user_card" @@ -60,21 +72,10 @@ const ( ) var ( - mixin = schema.User{}.Mixin() - mixinFields = [...][]ent.Field{ - mixin[0].Fields(), - } - fields = schema.User{}.Fields() - - // descOptionalInt is the schema descriptor for optional_int field. - descOptionalInt = mixinFields[0][0].Descriptor() // OptionalIntValidator is a validator for the "optional_int" field. It is called by the builders before save. - OptionalIntValidator = descOptionalInt.Validators[0].(func(int) error) - - // descLast is the schema descriptor for last field. - descLast = fields[2].Descriptor() + OptionalIntValidator func(int) error // DefaultLast holds the default value on creation for the last field. - DefaultLast = descLast.Default.(string) + DefaultLast string ) // Role defines the type for the role enum field. diff --git a/entc/integration/gremlin/ent/user_create.go b/entc/integration/gremlin/ent/user_create.go index 76230dc6f..608541dd4 100644 --- a/entc/integration/gremlin/ent/user_create.go +++ b/entc/integration/gremlin/ent/user_create.go @@ -22,30 +22,13 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - optional_int *int - age *int - name *string - last *string - nickname *string - phone *string - password *string - role *user.Role - card map[string]struct{} - pets map[string]struct{} - files map[string]struct{} - groups map[string]struct{} - friends map[string]struct{} - followers map[string]struct{} - following map[string]struct{} - team map[string]struct{} - spouse map[string]struct{} - children map[string]struct{} - parent map[string]struct{} + mutation *UserMutation + hooks []Hook } // SetOptionalInt sets the optional_int field. func (uc *UserCreate) SetOptionalInt(i int) *UserCreate { - uc.optional_int = &i + uc.mutation.SetOptionalInt(i) return uc } @@ -59,19 +42,19 @@ func (uc *UserCreate) SetNillableOptionalInt(i *int) *UserCreate { // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetLast sets the last field. func (uc *UserCreate) SetLast(s string) *UserCreate { - uc.last = &s + uc.mutation.SetLast(s) return uc } @@ -85,7 +68,7 @@ func (uc *UserCreate) SetNillableLast(s *string) *UserCreate { // SetNickname sets the nickname field. func (uc *UserCreate) SetNickname(s string) *UserCreate { - uc.nickname = &s + uc.mutation.SetNickname(s) return uc } @@ -99,7 +82,7 @@ func (uc *UserCreate) SetNillableNickname(s *string) *UserCreate { // SetPhone sets the phone field. func (uc *UserCreate) SetPhone(s string) *UserCreate { - uc.phone = &s + uc.mutation.SetPhone(s) return uc } @@ -113,7 +96,7 @@ func (uc *UserCreate) SetNillablePhone(s *string) *UserCreate { // SetPassword sets the password field. func (uc *UserCreate) SetPassword(s string) *UserCreate { - uc.password = &s + uc.mutation.SetPassword(s) return uc } @@ -127,7 +110,7 @@ func (uc *UserCreate) SetNillablePassword(s *string) *UserCreate { // SetRole sets the role field. func (uc *UserCreate) SetRole(u user.Role) *UserCreate { - uc.role = &u + uc.mutation.SetRole(u) return uc } @@ -141,10 +124,7 @@ func (uc *UserCreate) SetNillableRole(u *user.Role) *UserCreate { // SetCardID sets the card edge to Card by id. func (uc *UserCreate) SetCardID(id string) *UserCreate { - if uc.card == nil { - uc.card = make(map[string]struct{}) - } - uc.card[id] = struct{}{} + uc.mutation.SetCardID(id) return uc } @@ -163,12 +143,7 @@ func (uc *UserCreate) SetCard(c *Card) *UserCreate { // AddPetIDs adds the pets edge to Pet by ids. func (uc *UserCreate) AddPetIDs(ids ...string) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[string]struct{}) - } - for i := range ids { - uc.pets[ids[i]] = struct{}{} - } + uc.mutation.AddPetIDs(ids...) return uc } @@ -183,12 +158,7 @@ func (uc *UserCreate) AddPets(p ...*Pet) *UserCreate { // AddFileIDs adds the files edge to File by ids. func (uc *UserCreate) AddFileIDs(ids ...string) *UserCreate { - if uc.files == nil { - uc.files = make(map[string]struct{}) - } - for i := range ids { - uc.files[ids[i]] = struct{}{} - } + uc.mutation.AddFileIDs(ids...) return uc } @@ -203,12 +173,7 @@ func (uc *UserCreate) AddFiles(f ...*File) *UserCreate { // AddGroupIDs adds the groups edge to Group by ids. func (uc *UserCreate) AddGroupIDs(ids ...string) *UserCreate { - if uc.groups == nil { - uc.groups = make(map[string]struct{}) - } - for i := range ids { - uc.groups[ids[i]] = struct{}{} - } + uc.mutation.AddGroupIDs(ids...) return uc } @@ -223,12 +188,7 @@ func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { // AddFriendIDs adds the friends edge to User by ids. func (uc *UserCreate) AddFriendIDs(ids ...string) *UserCreate { - if uc.friends == nil { - uc.friends = make(map[string]struct{}) - } - for i := range ids { - uc.friends[ids[i]] = struct{}{} - } + uc.mutation.AddFriendIDs(ids...) return uc } @@ -243,12 +203,7 @@ func (uc *UserCreate) AddFriends(u ...*User) *UserCreate { // AddFollowerIDs adds the followers edge to User by ids. func (uc *UserCreate) AddFollowerIDs(ids ...string) *UserCreate { - if uc.followers == nil { - uc.followers = make(map[string]struct{}) - } - for i := range ids { - uc.followers[ids[i]] = struct{}{} - } + uc.mutation.AddFollowerIDs(ids...) return uc } @@ -263,12 +218,7 @@ func (uc *UserCreate) AddFollowers(u ...*User) *UserCreate { // AddFollowingIDs adds the following edge to User by ids. func (uc *UserCreate) AddFollowingIDs(ids ...string) *UserCreate { - if uc.following == nil { - uc.following = make(map[string]struct{}) - } - for i := range ids { - uc.following[ids[i]] = struct{}{} - } + uc.mutation.AddFollowingIDs(ids...) return uc } @@ -283,10 +233,7 @@ func (uc *UserCreate) AddFollowing(u ...*User) *UserCreate { // SetTeamID sets the team edge to Pet by id. func (uc *UserCreate) SetTeamID(id string) *UserCreate { - if uc.team == nil { - uc.team = make(map[string]struct{}) - } - uc.team[id] = struct{}{} + uc.mutation.SetTeamID(id) return uc } @@ -305,10 +252,7 @@ func (uc *UserCreate) SetTeam(p *Pet) *UserCreate { // SetSpouseID sets the spouse edge to User by id. func (uc *UserCreate) SetSpouseID(id string) *UserCreate { - if uc.spouse == nil { - uc.spouse = make(map[string]struct{}) - } - uc.spouse[id] = struct{}{} + uc.mutation.SetSpouseID(id) return uc } @@ -327,12 +271,7 @@ func (uc *UserCreate) SetSpouse(u *User) *UserCreate { // AddChildIDs adds the children edge to User by ids. func (uc *UserCreate) AddChildIDs(ids ...string) *UserCreate { - if uc.children == nil { - uc.children = make(map[string]struct{}) - } - for i := range ids { - uc.children[ids[i]] = struct{}{} - } + uc.mutation.AddChildIDs(ids...) return uc } @@ -347,10 +286,7 @@ func (uc *UserCreate) AddChildren(u ...*User) *UserCreate { // SetParentID sets the parent edge to User by id. func (uc *UserCreate) SetParentID(id string) *UserCreate { - if uc.parent == nil { - uc.parent = make(map[string]struct{}) - } - uc.parent[id] = struct{}{} + uc.mutation.SetParentID(id) return uc } @@ -369,41 +305,54 @@ func (uc *UserCreate) SetParent(u *User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.optional_int != nil { - if err := user.OptionalIntValidator(*uc.optional_int); err != nil { + if v, ok := uc.mutation.OptionalInt(); ok { + if err := user.OptionalIntValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"optional_int\": %v", err) } } - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if uc.last == nil { + if _, ok := uc.mutation.Last(); !ok { v := user.DefaultLast - uc.last = &v + uc.mutation.SetLast(v) } - if uc.role == nil { + if _, ok := uc.mutation.Role(); !ok { v := user.DefaultRole - uc.role = &v + uc.mutation.SetRole(v) } - if err := user.RoleValidator(*uc.role); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"role\": %v", err) + if v, ok := uc.mutation.Role(); ok { + if err := user.RoleValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"role\": %v", err) + } } - if len(uc.card) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"card\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.gremlinSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - if len(uc.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") - } - if len(uc.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") - } - if len(uc.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") - } - return uc.gremlinSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -438,93 +387,93 @@ func (uc *UserCreate) gremlin() *dsl.Traversal { } constraints := make([]*constraint, 0, 8) v := g.AddV(user.Label) - if uc.optional_int != nil { - v.Property(dsl.Single, user.FieldOptionalInt, *uc.optional_int) + if value, ok := uc.mutation.OptionalInt(); ok { + v.Property(dsl.Single, user.FieldOptionalInt, value) } - if uc.age != nil { - v.Property(dsl.Single, user.FieldAge, *uc.age) + if value, ok := uc.mutation.Age(); ok { + v.Property(dsl.Single, user.FieldAge, value) } - if uc.name != nil { - v.Property(dsl.Single, user.FieldName, *uc.name) + if value, ok := uc.mutation.Name(); ok { + v.Property(dsl.Single, user.FieldName, value) } - if uc.last != nil { - v.Property(dsl.Single, user.FieldLast, *uc.last) + if value, ok := uc.mutation.Last(); ok { + v.Property(dsl.Single, user.FieldLast, value) } - if uc.nickname != nil { + if value, ok := uc.mutation.Nickname(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(user.Label, user.FieldNickname, *uc.nickname).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldNickname, *uc.nickname)), + pred: g.V().Has(user.Label, user.FieldNickname, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldNickname, value)), }) - v.Property(dsl.Single, user.FieldNickname, *uc.nickname) + v.Property(dsl.Single, user.FieldNickname, value) } - if uc.phone != nil { + if value, ok := uc.mutation.Phone(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(user.Label, user.FieldPhone, *uc.phone).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldPhone, *uc.phone)), + pred: g.V().Has(user.Label, user.FieldPhone, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldPhone, value)), }) - v.Property(dsl.Single, user.FieldPhone, *uc.phone) + v.Property(dsl.Single, user.FieldPhone, value) } - if uc.password != nil { - v.Property(dsl.Single, user.FieldPassword, *uc.password) + if value, ok := uc.mutation.Password(); ok { + v.Property(dsl.Single, user.FieldPassword, value) } - if uc.role != nil { - v.Property(dsl.Single, user.FieldRole, *uc.role) + if value, ok := uc.mutation.Role(); ok { + v.Property(dsl.Single, user.FieldRole, value) } - for id := range uc.card { + for _, id := range uc.mutation.CardIDs() { v.AddE(user.CardLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.CardLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.CardLabel, id)), }) } - for id := range uc.pets { + for _, id := range uc.mutation.PetsIDs() { v.AddE(user.PetsLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.PetsLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.PetsLabel, id)), }) } - for id := range uc.files { + for _, id := range uc.mutation.FilesIDs() { v.AddE(user.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.FilesLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.FilesLabel, id)), }) } - for id := range uc.groups { + for _, id := range uc.mutation.GroupsIDs() { v.AddE(user.GroupsLabel).To(g.V(id)).OutV() } - for id := range uc.friends { + for _, id := range uc.mutation.FriendsIDs() { v.AddE(user.FriendsLabel).To(g.V(id)).OutV() } - for id := range uc.followers { + for _, id := range uc.mutation.FollowersIDs() { v.AddE(user.FollowingLabel).From(g.V(id)).InV() } - for id := range uc.following { + for _, id := range uc.mutation.FollowingIDs() { v.AddE(user.FollowingLabel).To(g.V(id)).OutV() } - for id := range uc.team { + for _, id := range uc.mutation.TeamIDs() { v.AddE(user.TeamLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.TeamLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.TeamLabel, id)), }) } - for id := range uc.spouse { + for _, id := range uc.mutation.SpouseIDs() { v.AddE(user.SpouseLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.SpouseLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.SpouseLabel, id)), }) } - for id := range uc.children { + for _, id := range uc.mutation.ChildrenIDs() { v.AddE(user.ParentLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.ParentLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.ParentLabel, id)), }) } - for id := range uc.parent { + for _, id := range uc.mutation.ParentIDs() { v.AddE(user.ParentLabel).To(g.V(id)).OutV() } if len(constraints) == 0 { diff --git a/entc/integration/gremlin/ent/user_delete.go b/entc/integration/gremlin/ent/user_delete.go index 53181de4f..92128df3f 100644 --- a/entc/integration/gremlin/ent/user_delete.go +++ b/entc/integration/gremlin/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/gremlin" "github.com/facebookincubator/ent/dialect/gremlin/graph/dsl" @@ -20,6 +21,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -31,7 +34,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.gremlinExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.gremlinExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.gremlinExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/gremlin/ent/user_update.go b/entc/integration/gremlin/ent/user_update.go index 646802cf2..c9bd605a6 100644 --- a/entc/integration/gremlin/ent/user_update.go +++ b/entc/integration/gremlin/ent/user_update.go @@ -8,7 +8,6 @@ package ent import ( "context" - "errors" "fmt" "github.com/facebookincubator/ent/dialect/gremlin" @@ -23,43 +22,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - optional_int *int - addoptional_int *int - clearoptional_int bool - age *int - addage *int - name *string - last *string - nickname *string - clearnickname bool - phone *string - clearphone bool - password *string - clearpassword bool - role *user.Role - card map[string]struct{} - pets map[string]struct{} - files map[string]struct{} - groups map[string]struct{} - friends map[string]struct{} - followers map[string]struct{} - following map[string]struct{} - team map[string]struct{} - spouse map[string]struct{} - children map[string]struct{} - parent map[string]struct{} - clearedCard bool - removedPets map[string]struct{} - removedFiles map[string]struct{} - removedGroups map[string]struct{} - removedFriends map[string]struct{} - removedFollowers map[string]struct{} - removedFollowing map[string]struct{} - clearedTeam bool - clearedSpouse bool - removedChildren map[string]struct{} - clearedParent bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -70,8 +35,8 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetOptionalInt sets the optional_int field. func (uu *UserUpdate) SetOptionalInt(i int) *UserUpdate { - uu.optional_int = &i - uu.addoptional_int = nil + uu.mutation.ResetOptionalInt() + uu.mutation.SetOptionalInt(i) return uu } @@ -85,47 +50,38 @@ func (uu *UserUpdate) SetNillableOptionalInt(i *int) *UserUpdate { // AddOptionalInt adds i to optional_int. func (uu *UserUpdate) AddOptionalInt(i int) *UserUpdate { - if uu.addoptional_int == nil { - uu.addoptional_int = &i - } else { - *uu.addoptional_int += i - } + uu.mutation.AddOptionalInt(i) return uu } // ClearOptionalInt clears the value of optional_int. func (uu *UserUpdate) ClearOptionalInt() *UserUpdate { - uu.optional_int = nil - uu.clearoptional_int = true + uu.mutation.ClearOptionalInt() return uu } // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetLast sets the last field. func (uu *UserUpdate) SetLast(s string) *UserUpdate { - uu.last = &s + uu.mutation.SetLast(s) return uu } @@ -139,7 +95,7 @@ func (uu *UserUpdate) SetNillableLast(s *string) *UserUpdate { // SetNickname sets the nickname field. func (uu *UserUpdate) SetNickname(s string) *UserUpdate { - uu.nickname = &s + uu.mutation.SetNickname(s) return uu } @@ -153,14 +109,13 @@ func (uu *UserUpdate) SetNillableNickname(s *string) *UserUpdate { // ClearNickname clears the value of nickname. func (uu *UserUpdate) ClearNickname() *UserUpdate { - uu.nickname = nil - uu.clearnickname = true + uu.mutation.ClearNickname() return uu } // SetPhone sets the phone field. func (uu *UserUpdate) SetPhone(s string) *UserUpdate { - uu.phone = &s + uu.mutation.SetPhone(s) return uu } @@ -174,14 +129,13 @@ func (uu *UserUpdate) SetNillablePhone(s *string) *UserUpdate { // ClearPhone clears the value of phone. func (uu *UserUpdate) ClearPhone() *UserUpdate { - uu.phone = nil - uu.clearphone = true + uu.mutation.ClearPhone() return uu } // SetPassword sets the password field. func (uu *UserUpdate) SetPassword(s string) *UserUpdate { - uu.password = &s + uu.mutation.SetPassword(s) return uu } @@ -195,14 +149,13 @@ func (uu *UserUpdate) SetNillablePassword(s *string) *UserUpdate { // ClearPassword clears the value of password. func (uu *UserUpdate) ClearPassword() *UserUpdate { - uu.password = nil - uu.clearpassword = true + uu.mutation.ClearPassword() return uu } // SetRole sets the role field. func (uu *UserUpdate) SetRole(u user.Role) *UserUpdate { - uu.role = &u + uu.mutation.SetRole(u) return uu } @@ -216,10 +169,7 @@ func (uu *UserUpdate) SetNillableRole(u *user.Role) *UserUpdate { // SetCardID sets the card edge to Card by id. func (uu *UserUpdate) SetCardID(id string) *UserUpdate { - if uu.card == nil { - uu.card = make(map[string]struct{}) - } - uu.card[id] = struct{}{} + uu.mutation.SetCardID(id) return uu } @@ -238,12 +188,7 @@ func (uu *UserUpdate) SetCard(c *Card) *UserUpdate { // AddPetIDs adds the pets edge to Pet by ids. func (uu *UserUpdate) AddPetIDs(ids ...string) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[string]struct{}) - } - for i := range ids { - uu.pets[ids[i]] = struct{}{} - } + uu.mutation.AddPetIDs(ids...) return uu } @@ -258,12 +203,7 @@ func (uu *UserUpdate) AddPets(p ...*Pet) *UserUpdate { // AddFileIDs adds the files edge to File by ids. func (uu *UserUpdate) AddFileIDs(ids ...string) *UserUpdate { - if uu.files == nil { - uu.files = make(map[string]struct{}) - } - for i := range ids { - uu.files[ids[i]] = struct{}{} - } + uu.mutation.AddFileIDs(ids...) return uu } @@ -278,12 +218,7 @@ func (uu *UserUpdate) AddFiles(f ...*File) *UserUpdate { // AddGroupIDs adds the groups edge to Group by ids. func (uu *UserUpdate) AddGroupIDs(ids ...string) *UserUpdate { - if uu.groups == nil { - uu.groups = make(map[string]struct{}) - } - for i := range ids { - uu.groups[ids[i]] = struct{}{} - } + uu.mutation.AddGroupIDs(ids...) return uu } @@ -298,12 +233,7 @@ func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { // AddFriendIDs adds the friends edge to User by ids. func (uu *UserUpdate) AddFriendIDs(ids ...string) *UserUpdate { - if uu.friends == nil { - uu.friends = make(map[string]struct{}) - } - for i := range ids { - uu.friends[ids[i]] = struct{}{} - } + uu.mutation.AddFriendIDs(ids...) return uu } @@ -318,12 +248,7 @@ func (uu *UserUpdate) AddFriends(u ...*User) *UserUpdate { // AddFollowerIDs adds the followers edge to User by ids. func (uu *UserUpdate) AddFollowerIDs(ids ...string) *UserUpdate { - if uu.followers == nil { - uu.followers = make(map[string]struct{}) - } - for i := range ids { - uu.followers[ids[i]] = struct{}{} - } + uu.mutation.AddFollowerIDs(ids...) return uu } @@ -338,12 +263,7 @@ func (uu *UserUpdate) AddFollowers(u ...*User) *UserUpdate { // AddFollowingIDs adds the following edge to User by ids. func (uu *UserUpdate) AddFollowingIDs(ids ...string) *UserUpdate { - if uu.following == nil { - uu.following = make(map[string]struct{}) - } - for i := range ids { - uu.following[ids[i]] = struct{}{} - } + uu.mutation.AddFollowingIDs(ids...) return uu } @@ -358,10 +278,7 @@ func (uu *UserUpdate) AddFollowing(u ...*User) *UserUpdate { // SetTeamID sets the team edge to Pet by id. func (uu *UserUpdate) SetTeamID(id string) *UserUpdate { - if uu.team == nil { - uu.team = make(map[string]struct{}) - } - uu.team[id] = struct{}{} + uu.mutation.SetTeamID(id) return uu } @@ -380,10 +297,7 @@ func (uu *UserUpdate) SetTeam(p *Pet) *UserUpdate { // SetSpouseID sets the spouse edge to User by id. func (uu *UserUpdate) SetSpouseID(id string) *UserUpdate { - if uu.spouse == nil { - uu.spouse = make(map[string]struct{}) - } - uu.spouse[id] = struct{}{} + uu.mutation.SetSpouseID(id) return uu } @@ -402,12 +316,7 @@ func (uu *UserUpdate) SetSpouse(u *User) *UserUpdate { // AddChildIDs adds the children edge to User by ids. func (uu *UserUpdate) AddChildIDs(ids ...string) *UserUpdate { - if uu.children == nil { - uu.children = make(map[string]struct{}) - } - for i := range ids { - uu.children[ids[i]] = struct{}{} - } + uu.mutation.AddChildIDs(ids...) return uu } @@ -422,10 +331,7 @@ func (uu *UserUpdate) AddChildren(u ...*User) *UserUpdate { // SetParentID sets the parent edge to User by id. func (uu *UserUpdate) SetParentID(id string) *UserUpdate { - if uu.parent == nil { - uu.parent = make(map[string]struct{}) - } - uu.parent[id] = struct{}{} + uu.mutation.SetParentID(id) return uu } @@ -444,18 +350,13 @@ func (uu *UserUpdate) SetParent(u *User) *UserUpdate { // ClearCard clears the card edge to Card. func (uu *UserUpdate) ClearCard() *UserUpdate { - uu.clearedCard = true + uu.mutation.ClearCard() return uu } // RemovePetIDs removes the pets edge to Pet by ids. func (uu *UserUpdate) RemovePetIDs(ids ...string) *UserUpdate { - if uu.removedPets == nil { - uu.removedPets = make(map[string]struct{}) - } - for i := range ids { - uu.removedPets[ids[i]] = struct{}{} - } + uu.mutation.RemovePetIDs(ids...) return uu } @@ -470,12 +371,7 @@ func (uu *UserUpdate) RemovePets(p ...*Pet) *UserUpdate { // RemoveFileIDs removes the files edge to File by ids. func (uu *UserUpdate) RemoveFileIDs(ids ...string) *UserUpdate { - if uu.removedFiles == nil { - uu.removedFiles = make(map[string]struct{}) - } - for i := range ids { - uu.removedFiles[ids[i]] = struct{}{} - } + uu.mutation.RemoveFileIDs(ids...) return uu } @@ -490,12 +386,7 @@ func (uu *UserUpdate) RemoveFiles(f ...*File) *UserUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (uu *UserUpdate) RemoveGroupIDs(ids ...string) *UserUpdate { - if uu.removedGroups == nil { - uu.removedGroups = make(map[string]struct{}) - } - for i := range ids { - uu.removedGroups[ids[i]] = struct{}{} - } + uu.mutation.RemoveGroupIDs(ids...) return uu } @@ -510,12 +401,7 @@ func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { // RemoveFriendIDs removes the friends edge to User by ids. func (uu *UserUpdate) RemoveFriendIDs(ids ...string) *UserUpdate { - if uu.removedFriends == nil { - uu.removedFriends = make(map[string]struct{}) - } - for i := range ids { - uu.removedFriends[ids[i]] = struct{}{} - } + uu.mutation.RemoveFriendIDs(ids...) return uu } @@ -530,12 +416,7 @@ func (uu *UserUpdate) RemoveFriends(u ...*User) *UserUpdate { // RemoveFollowerIDs removes the followers edge to User by ids. func (uu *UserUpdate) RemoveFollowerIDs(ids ...string) *UserUpdate { - if uu.removedFollowers == nil { - uu.removedFollowers = make(map[string]struct{}) - } - for i := range ids { - uu.removedFollowers[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowerIDs(ids...) return uu } @@ -550,12 +431,7 @@ func (uu *UserUpdate) RemoveFollowers(u ...*User) *UserUpdate { // RemoveFollowingIDs removes the following edge to User by ids. func (uu *UserUpdate) RemoveFollowingIDs(ids ...string) *UserUpdate { - if uu.removedFollowing == nil { - uu.removedFollowing = make(map[string]struct{}) - } - for i := range ids { - uu.removedFollowing[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowingIDs(ids...) return uu } @@ -570,24 +446,19 @@ func (uu *UserUpdate) RemoveFollowing(u ...*User) *UserUpdate { // ClearTeam clears the team edge to Pet. func (uu *UserUpdate) ClearTeam() *UserUpdate { - uu.clearedTeam = true + uu.mutation.ClearTeam() return uu } // ClearSpouse clears the spouse edge to User. func (uu *UserUpdate) ClearSpouse() *UserUpdate { - uu.clearedSpouse = true + uu.mutation.ClearSpouse() return uu } // RemoveChildIDs removes the children edge to User by ids. func (uu *UserUpdate) RemoveChildIDs(ids ...string) *UserUpdate { - if uu.removedChildren == nil { - uu.removedChildren = make(map[string]struct{}) - } - for i := range ids { - uu.removedChildren[ids[i]] = struct{}{} - } + uu.mutation.RemoveChildIDs(ids...) return uu } @@ -602,35 +473,47 @@ func (uu *UserUpdate) RemoveChildren(u ...*User) *UserUpdate { // ClearParent clears the parent edge to User. func (uu *UserUpdate) ClearParent() *UserUpdate { - uu.clearedParent = true + uu.mutation.ClearParent() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if uu.optional_int != nil { - if err := user.OptionalIntValidator(*uu.optional_int); err != nil { + if v, ok := uu.mutation.OptionalInt(); ok { + if err := user.OptionalIntValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"optional_int\": %v", err) } } - if uu.role != nil { - if err := user.RoleValidator(*uu.role); err != nil { + if v, ok := uu.mutation.Role(); ok { + if err := user.RoleValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"role\": %v", err) } } - if len(uu.card) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"card\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.gremlinSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - if len(uu.team) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"team\"") - } - if len(uu.spouse) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"spouse\"") - } - if len(uu.parent) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"parent\"") - } - return uu.gremlinSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -683,137 +566,137 @@ func (uu *UserUpdate) gremlin() *dsl.Traversal { trs []*dsl.Traversal ) - if value := uu.optional_int; value != nil { - v.Property(dsl.Single, user.FieldOptionalInt, *value) + if value, ok := uu.mutation.OptionalInt(); ok { + v.Property(dsl.Single, user.FieldOptionalInt, value) } - if value := uu.addoptional_int; value != nil { - v.Property(dsl.Single, user.FieldOptionalInt, __.Union(__.Values(user.FieldOptionalInt), __.Constant(*value)).Sum()) + if value, ok := uu.mutation.AddedOptionalInt(); ok { + v.Property(dsl.Single, user.FieldOptionalInt, __.Union(__.Values(user.FieldOptionalInt), __.Constant(value)).Sum()) } - if value := uu.age; value != nil { - v.Property(dsl.Single, user.FieldAge, *value) + if value, ok := uu.mutation.Age(); ok { + v.Property(dsl.Single, user.FieldAge, value) } - if value := uu.addage; value != nil { - v.Property(dsl.Single, user.FieldAge, __.Union(__.Values(user.FieldAge), __.Constant(*value)).Sum()) + if value, ok := uu.mutation.AddedAge(); ok { + v.Property(dsl.Single, user.FieldAge, __.Union(__.Values(user.FieldAge), __.Constant(value)).Sum()) } - if value := uu.name; value != nil { - v.Property(dsl.Single, user.FieldName, *value) + if value, ok := uu.mutation.Name(); ok { + v.Property(dsl.Single, user.FieldName, value) } - if value := uu.last; value != nil { - v.Property(dsl.Single, user.FieldLast, *value) + if value, ok := uu.mutation.Last(); ok { + v.Property(dsl.Single, user.FieldLast, value) } - if value := uu.nickname; value != nil { + if value, ok := uu.mutation.Nickname(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(user.Label, user.FieldNickname, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldNickname, *value)), + pred: g.V().Has(user.Label, user.FieldNickname, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldNickname, value)), }) - v.Property(dsl.Single, user.FieldNickname, *value) + v.Property(dsl.Single, user.FieldNickname, value) } - if value := uu.phone; value != nil { + if value, ok := uu.mutation.Phone(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(user.Label, user.FieldPhone, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldPhone, *value)), + pred: g.V().Has(user.Label, user.FieldPhone, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldPhone, value)), }) - v.Property(dsl.Single, user.FieldPhone, *value) + v.Property(dsl.Single, user.FieldPhone, value) } - if value := uu.password; value != nil { - v.Property(dsl.Single, user.FieldPassword, *value) + if value, ok := uu.mutation.Password(); ok { + v.Property(dsl.Single, user.FieldPassword, value) } - if value := uu.role; value != nil { - v.Property(dsl.Single, user.FieldRole, *value) + if value, ok := uu.mutation.Role(); ok { + v.Property(dsl.Single, user.FieldRole, value) } var properties []interface{} - if uu.clearoptional_int { + if uu.mutation.OptionalIntCleared() { properties = append(properties, user.FieldOptionalInt) } - if uu.clearnickname { + if uu.mutation.NicknameCleared() { properties = append(properties, user.FieldNickname) } - if uu.clearphone { + if uu.mutation.PhoneCleared() { properties = append(properties, user.FieldPhone) } - if uu.clearpassword { + if uu.mutation.PasswordCleared() { properties = append(properties, user.FieldPassword) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if uu.clearedCard { + if uu.mutation.CardCleared() { tr := rv.Clone().OutE(user.CardLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.card { + for _, id := range uu.mutation.CardIDs() { v.AddE(user.CardLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.CardLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.CardLabel, id)), }) } - for id := range uu.removedPets { + for _, id := range uu.mutation.RemovedPetsIDs() { tr := rv.Clone().OutE(user.PetsLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.pets { + for _, id := range uu.mutation.PetsIDs() { v.AddE(user.PetsLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.PetsLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.PetsLabel, id)), }) } - for id := range uu.removedFiles { + for _, id := range uu.mutation.RemovedFilesIDs() { tr := rv.Clone().OutE(user.FilesLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.files { + for _, id := range uu.mutation.FilesIDs() { v.AddE(user.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.FilesLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.FilesLabel, id)), }) } - for id := range uu.removedGroups { + for _, id := range uu.mutation.RemovedGroupsIDs() { tr := rv.Clone().OutE(user.GroupsLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.groups { + for _, id := range uu.mutation.GroupsIDs() { v.AddE(user.GroupsLabel).To(g.V(id)).OutV() } - for id := range uu.removedFriends { + for _, id := range uu.mutation.RemovedFriendsIDs() { tr := rv.Clone().BothE(user.FriendsLabel).Where(__.Or(__.InV().HasID(id), __.OutV().HasID(id))).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.friends { + for _, id := range uu.mutation.FriendsIDs() { v.AddE(user.FriendsLabel).To(g.V(id)).OutV() } - for id := range uu.removedFollowers { + for _, id := range uu.mutation.RemovedFollowersIDs() { tr := rv.Clone().InE(user.FollowingLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.followers { + for _, id := range uu.mutation.FollowersIDs() { v.AddE(user.FollowingLabel).From(g.V(id)).InV() } - for id := range uu.removedFollowing { + for _, id := range uu.mutation.RemovedFollowingIDs() { tr := rv.Clone().OutE(user.FollowingLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.following { + for _, id := range uu.mutation.FollowingIDs() { v.AddE(user.FollowingLabel).To(g.V(id)).OutV() } - if uu.clearedTeam { + if uu.mutation.TeamCleared() { tr := rv.Clone().OutE(user.TeamLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.team { + for _, id := range uu.mutation.TeamIDs() { v.AddE(user.TeamLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.TeamLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.TeamLabel, id)), }) } - if uu.clearedSpouse { + if uu.mutation.SpouseCleared() { tr := rv.Clone().BothE(user.SpouseLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.spouse { + for _, id := range uu.mutation.SpouseIDs() { v.AddE(user.SpouseLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: rv.Clone().Both(user.SpouseLabel).Count(), @@ -824,22 +707,22 @@ func (uu *UserUpdate) gremlin() *dsl.Traversal { test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.SpouseLabel, id)), }) } - for id := range uu.removedChildren { + for _, id := range uu.mutation.RemovedChildrenIDs() { tr := rv.Clone().InE(user.ParentLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.children { + for _, id := range uu.mutation.ChildrenIDs() { v.AddE(user.ParentLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.ParentLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.ParentLabel, id)), }) } - if uu.clearedParent { + if uu.mutation.ParentCleared() { tr := rv.Clone().OutE(user.ParentLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uu.parent { + for _, id := range uu.mutation.ParentIDs() { v.AddE(user.ParentLabel).To(g.V(id)).OutV() } v.Count() @@ -860,49 +743,14 @@ func (uu *UserUpdate) gremlin() *dsl.Traversal { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id string - optional_int *int - addoptional_int *int - clearoptional_int bool - age *int - addage *int - name *string - last *string - nickname *string - clearnickname bool - phone *string - clearphone bool - password *string - clearpassword bool - role *user.Role - card map[string]struct{} - pets map[string]struct{} - files map[string]struct{} - groups map[string]struct{} - friends map[string]struct{} - followers map[string]struct{} - following map[string]struct{} - team map[string]struct{} - spouse map[string]struct{} - children map[string]struct{} - parent map[string]struct{} - clearedCard bool - removedPets map[string]struct{} - removedFiles map[string]struct{} - removedGroups map[string]struct{} - removedFriends map[string]struct{} - removedFollowers map[string]struct{} - removedFollowing map[string]struct{} - clearedTeam bool - clearedSpouse bool - removedChildren map[string]struct{} - clearedParent bool + hooks []Hook + mutation *UserMutation } // SetOptionalInt sets the optional_int field. func (uuo *UserUpdateOne) SetOptionalInt(i int) *UserUpdateOne { - uuo.optional_int = &i - uuo.addoptional_int = nil + uuo.mutation.ResetOptionalInt() + uuo.mutation.SetOptionalInt(i) return uuo } @@ -916,47 +764,38 @@ func (uuo *UserUpdateOne) SetNillableOptionalInt(i *int) *UserUpdateOne { // AddOptionalInt adds i to optional_int. func (uuo *UserUpdateOne) AddOptionalInt(i int) *UserUpdateOne { - if uuo.addoptional_int == nil { - uuo.addoptional_int = &i - } else { - *uuo.addoptional_int += i - } + uuo.mutation.AddOptionalInt(i) return uuo } // ClearOptionalInt clears the value of optional_int. func (uuo *UserUpdateOne) ClearOptionalInt() *UserUpdateOne { - uuo.optional_int = nil - uuo.clearoptional_int = true + uuo.mutation.ClearOptionalInt() return uuo } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetLast sets the last field. func (uuo *UserUpdateOne) SetLast(s string) *UserUpdateOne { - uuo.last = &s + uuo.mutation.SetLast(s) return uuo } @@ -970,7 +809,7 @@ func (uuo *UserUpdateOne) SetNillableLast(s *string) *UserUpdateOne { // SetNickname sets the nickname field. func (uuo *UserUpdateOne) SetNickname(s string) *UserUpdateOne { - uuo.nickname = &s + uuo.mutation.SetNickname(s) return uuo } @@ -984,14 +823,13 @@ func (uuo *UserUpdateOne) SetNillableNickname(s *string) *UserUpdateOne { // ClearNickname clears the value of nickname. func (uuo *UserUpdateOne) ClearNickname() *UserUpdateOne { - uuo.nickname = nil - uuo.clearnickname = true + uuo.mutation.ClearNickname() return uuo } // SetPhone sets the phone field. func (uuo *UserUpdateOne) SetPhone(s string) *UserUpdateOne { - uuo.phone = &s + uuo.mutation.SetPhone(s) return uuo } @@ -1005,14 +843,13 @@ func (uuo *UserUpdateOne) SetNillablePhone(s *string) *UserUpdateOne { // ClearPhone clears the value of phone. func (uuo *UserUpdateOne) ClearPhone() *UserUpdateOne { - uuo.phone = nil - uuo.clearphone = true + uuo.mutation.ClearPhone() return uuo } // SetPassword sets the password field. func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne { - uuo.password = &s + uuo.mutation.SetPassword(s) return uuo } @@ -1026,14 +863,13 @@ func (uuo *UserUpdateOne) SetNillablePassword(s *string) *UserUpdateOne { // ClearPassword clears the value of password. func (uuo *UserUpdateOne) ClearPassword() *UserUpdateOne { - uuo.password = nil - uuo.clearpassword = true + uuo.mutation.ClearPassword() return uuo } // SetRole sets the role field. func (uuo *UserUpdateOne) SetRole(u user.Role) *UserUpdateOne { - uuo.role = &u + uuo.mutation.SetRole(u) return uuo } @@ -1047,10 +883,7 @@ func (uuo *UserUpdateOne) SetNillableRole(u *user.Role) *UserUpdateOne { // SetCardID sets the card edge to Card by id. func (uuo *UserUpdateOne) SetCardID(id string) *UserUpdateOne { - if uuo.card == nil { - uuo.card = make(map[string]struct{}) - } - uuo.card[id] = struct{}{} + uuo.mutation.SetCardID(id) return uuo } @@ -1069,12 +902,7 @@ func (uuo *UserUpdateOne) SetCard(c *Card) *UserUpdateOne { // AddPetIDs adds the pets edge to Pet by ids. func (uuo *UserUpdateOne) AddPetIDs(ids ...string) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[string]struct{}) - } - for i := range ids { - uuo.pets[ids[i]] = struct{}{} - } + uuo.mutation.AddPetIDs(ids...) return uuo } @@ -1089,12 +917,7 @@ func (uuo *UserUpdateOne) AddPets(p ...*Pet) *UserUpdateOne { // AddFileIDs adds the files edge to File by ids. func (uuo *UserUpdateOne) AddFileIDs(ids ...string) *UserUpdateOne { - if uuo.files == nil { - uuo.files = make(map[string]struct{}) - } - for i := range ids { - uuo.files[ids[i]] = struct{}{} - } + uuo.mutation.AddFileIDs(ids...) return uuo } @@ -1109,12 +932,7 @@ func (uuo *UserUpdateOne) AddFiles(f ...*File) *UserUpdateOne { // AddGroupIDs adds the groups edge to Group by ids. func (uuo *UserUpdateOne) AddGroupIDs(ids ...string) *UserUpdateOne { - if uuo.groups == nil { - uuo.groups = make(map[string]struct{}) - } - for i := range ids { - uuo.groups[ids[i]] = struct{}{} - } + uuo.mutation.AddGroupIDs(ids...) return uuo } @@ -1129,12 +947,7 @@ func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { // AddFriendIDs adds the friends edge to User by ids. func (uuo *UserUpdateOne) AddFriendIDs(ids ...string) *UserUpdateOne { - if uuo.friends == nil { - uuo.friends = make(map[string]struct{}) - } - for i := range ids { - uuo.friends[ids[i]] = struct{}{} - } + uuo.mutation.AddFriendIDs(ids...) return uuo } @@ -1149,12 +962,7 @@ func (uuo *UserUpdateOne) AddFriends(u ...*User) *UserUpdateOne { // AddFollowerIDs adds the followers edge to User by ids. func (uuo *UserUpdateOne) AddFollowerIDs(ids ...string) *UserUpdateOne { - if uuo.followers == nil { - uuo.followers = make(map[string]struct{}) - } - for i := range ids { - uuo.followers[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowerIDs(ids...) return uuo } @@ -1169,12 +977,7 @@ func (uuo *UserUpdateOne) AddFollowers(u ...*User) *UserUpdateOne { // AddFollowingIDs adds the following edge to User by ids. func (uuo *UserUpdateOne) AddFollowingIDs(ids ...string) *UserUpdateOne { - if uuo.following == nil { - uuo.following = make(map[string]struct{}) - } - for i := range ids { - uuo.following[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowingIDs(ids...) return uuo } @@ -1189,10 +992,7 @@ func (uuo *UserUpdateOne) AddFollowing(u ...*User) *UserUpdateOne { // SetTeamID sets the team edge to Pet by id. func (uuo *UserUpdateOne) SetTeamID(id string) *UserUpdateOne { - if uuo.team == nil { - uuo.team = make(map[string]struct{}) - } - uuo.team[id] = struct{}{} + uuo.mutation.SetTeamID(id) return uuo } @@ -1211,10 +1011,7 @@ func (uuo *UserUpdateOne) SetTeam(p *Pet) *UserUpdateOne { // SetSpouseID sets the spouse edge to User by id. func (uuo *UserUpdateOne) SetSpouseID(id string) *UserUpdateOne { - if uuo.spouse == nil { - uuo.spouse = make(map[string]struct{}) - } - uuo.spouse[id] = struct{}{} + uuo.mutation.SetSpouseID(id) return uuo } @@ -1233,12 +1030,7 @@ func (uuo *UserUpdateOne) SetSpouse(u *User) *UserUpdateOne { // AddChildIDs adds the children edge to User by ids. func (uuo *UserUpdateOne) AddChildIDs(ids ...string) *UserUpdateOne { - if uuo.children == nil { - uuo.children = make(map[string]struct{}) - } - for i := range ids { - uuo.children[ids[i]] = struct{}{} - } + uuo.mutation.AddChildIDs(ids...) return uuo } @@ -1253,10 +1045,7 @@ func (uuo *UserUpdateOne) AddChildren(u ...*User) *UserUpdateOne { // SetParentID sets the parent edge to User by id. func (uuo *UserUpdateOne) SetParentID(id string) *UserUpdateOne { - if uuo.parent == nil { - uuo.parent = make(map[string]struct{}) - } - uuo.parent[id] = struct{}{} + uuo.mutation.SetParentID(id) return uuo } @@ -1275,18 +1064,13 @@ func (uuo *UserUpdateOne) SetParent(u *User) *UserUpdateOne { // ClearCard clears the card edge to Card. func (uuo *UserUpdateOne) ClearCard() *UserUpdateOne { - uuo.clearedCard = true + uuo.mutation.ClearCard() return uuo } // RemovePetIDs removes the pets edge to Pet by ids. func (uuo *UserUpdateOne) RemovePetIDs(ids ...string) *UserUpdateOne { - if uuo.removedPets == nil { - uuo.removedPets = make(map[string]struct{}) - } - for i := range ids { - uuo.removedPets[ids[i]] = struct{}{} - } + uuo.mutation.RemovePetIDs(ids...) return uuo } @@ -1301,12 +1085,7 @@ func (uuo *UserUpdateOne) RemovePets(p ...*Pet) *UserUpdateOne { // RemoveFileIDs removes the files edge to File by ids. func (uuo *UserUpdateOne) RemoveFileIDs(ids ...string) *UserUpdateOne { - if uuo.removedFiles == nil { - uuo.removedFiles = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFiles[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFileIDs(ids...) return uuo } @@ -1321,12 +1100,7 @@ func (uuo *UserUpdateOne) RemoveFiles(f ...*File) *UserUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...string) *UserUpdateOne { - if uuo.removedGroups == nil { - uuo.removedGroups = make(map[string]struct{}) - } - for i := range ids { - uuo.removedGroups[ids[i]] = struct{}{} - } + uuo.mutation.RemoveGroupIDs(ids...) return uuo } @@ -1341,12 +1115,7 @@ func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { // RemoveFriendIDs removes the friends edge to User by ids. func (uuo *UserUpdateOne) RemoveFriendIDs(ids ...string) *UserUpdateOne { - if uuo.removedFriends == nil { - uuo.removedFriends = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFriends[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFriendIDs(ids...) return uuo } @@ -1361,12 +1130,7 @@ func (uuo *UserUpdateOne) RemoveFriends(u ...*User) *UserUpdateOne { // RemoveFollowerIDs removes the followers edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowerIDs(ids ...string) *UserUpdateOne { - if uuo.removedFollowers == nil { - uuo.removedFollowers = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFollowers[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowerIDs(ids...) return uuo } @@ -1381,12 +1145,7 @@ func (uuo *UserUpdateOne) RemoveFollowers(u ...*User) *UserUpdateOne { // RemoveFollowingIDs removes the following edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowingIDs(ids ...string) *UserUpdateOne { - if uuo.removedFollowing == nil { - uuo.removedFollowing = make(map[string]struct{}) - } - for i := range ids { - uuo.removedFollowing[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowingIDs(ids...) return uuo } @@ -1401,24 +1160,19 @@ func (uuo *UserUpdateOne) RemoveFollowing(u ...*User) *UserUpdateOne { // ClearTeam clears the team edge to Pet. func (uuo *UserUpdateOne) ClearTeam() *UserUpdateOne { - uuo.clearedTeam = true + uuo.mutation.ClearTeam() return uuo } // ClearSpouse clears the spouse edge to User. func (uuo *UserUpdateOne) ClearSpouse() *UserUpdateOne { - uuo.clearedSpouse = true + uuo.mutation.ClearSpouse() return uuo } // RemoveChildIDs removes the children edge to User by ids. func (uuo *UserUpdateOne) RemoveChildIDs(ids ...string) *UserUpdateOne { - if uuo.removedChildren == nil { - uuo.removedChildren = make(map[string]struct{}) - } - for i := range ids { - uuo.removedChildren[ids[i]] = struct{}{} - } + uuo.mutation.RemoveChildIDs(ids...) return uuo } @@ -1433,35 +1187,47 @@ func (uuo *UserUpdateOne) RemoveChildren(u ...*User) *UserUpdateOne { // ClearParent clears the parent edge to User. func (uuo *UserUpdateOne) ClearParent() *UserUpdateOne { - uuo.clearedParent = true + uuo.mutation.ClearParent() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if uuo.optional_int != nil { - if err := user.OptionalIntValidator(*uuo.optional_int); err != nil { + if v, ok := uuo.mutation.OptionalInt(); ok { + if err := user.OptionalIntValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"optional_int\": %v", err) } } - if uuo.role != nil { - if err := user.RoleValidator(*uuo.role); err != nil { + if v, ok := uuo.mutation.Role(); ok { + if err := user.RoleValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"role\": %v", err) } } - if len(uuo.card) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"card\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.gremlinSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.gremlinSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - if len(uuo.team) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"team\"") - } - if len(uuo.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") - } - if len(uuo.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") - } - return uuo.gremlinSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -1488,7 +1254,11 @@ func (uuo *UserUpdateOne) ExecX(ctx context.Context) { func (uuo *UserUpdateOne) gremlinSave(ctx context.Context) (*User, error) { res := &gremlin.Response{} - query, bindings := uuo.gremlin(uuo.id).Query() + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + query, bindings := uuo.gremlin(id).Query() if err := uuo.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } @@ -1515,137 +1285,137 @@ func (uuo *UserUpdateOne) gremlin(id string) *dsl.Traversal { trs []*dsl.Traversal ) - if value := uuo.optional_int; value != nil { - v.Property(dsl.Single, user.FieldOptionalInt, *value) + if value, ok := uuo.mutation.OptionalInt(); ok { + v.Property(dsl.Single, user.FieldOptionalInt, value) } - if value := uuo.addoptional_int; value != nil { - v.Property(dsl.Single, user.FieldOptionalInt, __.Union(__.Values(user.FieldOptionalInt), __.Constant(*value)).Sum()) + if value, ok := uuo.mutation.AddedOptionalInt(); ok { + v.Property(dsl.Single, user.FieldOptionalInt, __.Union(__.Values(user.FieldOptionalInt), __.Constant(value)).Sum()) } - if value := uuo.age; value != nil { - v.Property(dsl.Single, user.FieldAge, *value) + if value, ok := uuo.mutation.Age(); ok { + v.Property(dsl.Single, user.FieldAge, value) } - if value := uuo.addage; value != nil { - v.Property(dsl.Single, user.FieldAge, __.Union(__.Values(user.FieldAge), __.Constant(*value)).Sum()) + if value, ok := uuo.mutation.AddedAge(); ok { + v.Property(dsl.Single, user.FieldAge, __.Union(__.Values(user.FieldAge), __.Constant(value)).Sum()) } - if value := uuo.name; value != nil { - v.Property(dsl.Single, user.FieldName, *value) + if value, ok := uuo.mutation.Name(); ok { + v.Property(dsl.Single, user.FieldName, value) } - if value := uuo.last; value != nil { - v.Property(dsl.Single, user.FieldLast, *value) + if value, ok := uuo.mutation.Last(); ok { + v.Property(dsl.Single, user.FieldLast, value) } - if value := uuo.nickname; value != nil { + if value, ok := uuo.mutation.Nickname(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(user.Label, user.FieldNickname, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldNickname, *value)), + pred: g.V().Has(user.Label, user.FieldNickname, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldNickname, value)), }) - v.Property(dsl.Single, user.FieldNickname, *value) + v.Property(dsl.Single, user.FieldNickname, value) } - if value := uuo.phone; value != nil { + if value, ok := uuo.mutation.Phone(); ok { constraints = append(constraints, &constraint{ - pred: g.V().Has(user.Label, user.FieldPhone, *value).Count(), - test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldPhone, *value)), + pred: g.V().Has(user.Label, user.FieldPhone, value).Count(), + test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField(user.Label, user.FieldPhone, value)), }) - v.Property(dsl.Single, user.FieldPhone, *value) + v.Property(dsl.Single, user.FieldPhone, value) } - if value := uuo.password; value != nil { - v.Property(dsl.Single, user.FieldPassword, *value) + if value, ok := uuo.mutation.Password(); ok { + v.Property(dsl.Single, user.FieldPassword, value) } - if value := uuo.role; value != nil { - v.Property(dsl.Single, user.FieldRole, *value) + if value, ok := uuo.mutation.Role(); ok { + v.Property(dsl.Single, user.FieldRole, value) } var properties []interface{} - if uuo.clearoptional_int { + if uuo.mutation.OptionalIntCleared() { properties = append(properties, user.FieldOptionalInt) } - if uuo.clearnickname { + if uuo.mutation.NicknameCleared() { properties = append(properties, user.FieldNickname) } - if uuo.clearphone { + if uuo.mutation.PhoneCleared() { properties = append(properties, user.FieldPhone) } - if uuo.clearpassword { + if uuo.mutation.PasswordCleared() { properties = append(properties, user.FieldPassword) } if len(properties) > 0 { v.SideEffect(__.Properties(properties...).Drop()) } - if uuo.clearedCard { + if uuo.mutation.CardCleared() { tr := rv.Clone().OutE(user.CardLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.card { + for _, id := range uuo.mutation.CardIDs() { v.AddE(user.CardLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.CardLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.CardLabel, id)), }) } - for id := range uuo.removedPets { + for _, id := range uuo.mutation.RemovedPetsIDs() { tr := rv.Clone().OutE(user.PetsLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.pets { + for _, id := range uuo.mutation.PetsIDs() { v.AddE(user.PetsLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.PetsLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.PetsLabel, id)), }) } - for id := range uuo.removedFiles { + for _, id := range uuo.mutation.RemovedFilesIDs() { tr := rv.Clone().OutE(user.FilesLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.files { + for _, id := range uuo.mutation.FilesIDs() { v.AddE(user.FilesLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.FilesLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.FilesLabel, id)), }) } - for id := range uuo.removedGroups { + for _, id := range uuo.mutation.RemovedGroupsIDs() { tr := rv.Clone().OutE(user.GroupsLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.groups { + for _, id := range uuo.mutation.GroupsIDs() { v.AddE(user.GroupsLabel).To(g.V(id)).OutV() } - for id := range uuo.removedFriends { + for _, id := range uuo.mutation.RemovedFriendsIDs() { tr := rv.Clone().BothE(user.FriendsLabel).Where(__.Or(__.InV().HasID(id), __.OutV().HasID(id))).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.friends { + for _, id := range uuo.mutation.FriendsIDs() { v.AddE(user.FriendsLabel).To(g.V(id)).OutV() } - for id := range uuo.removedFollowers { + for _, id := range uuo.mutation.RemovedFollowersIDs() { tr := rv.Clone().InE(user.FollowingLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.followers { + for _, id := range uuo.mutation.FollowersIDs() { v.AddE(user.FollowingLabel).From(g.V(id)).InV() } - for id := range uuo.removedFollowing { + for _, id := range uuo.mutation.RemovedFollowingIDs() { tr := rv.Clone().OutE(user.FollowingLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.following { + for _, id := range uuo.mutation.FollowingIDs() { v.AddE(user.FollowingLabel).To(g.V(id)).OutV() } - if uuo.clearedTeam { + if uuo.mutation.TeamCleared() { tr := rv.Clone().OutE(user.TeamLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.team { + for _, id := range uuo.mutation.TeamIDs() { v.AddE(user.TeamLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.TeamLabel).InV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.TeamLabel, id)), }) } - if uuo.clearedSpouse { + if uuo.mutation.SpouseCleared() { tr := rv.Clone().BothE(user.SpouseLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.spouse { + for _, id := range uuo.mutation.SpouseIDs() { v.AddE(user.SpouseLabel).To(g.V(id)).OutV() constraints = append(constraints, &constraint{ pred: rv.Clone().Both(user.SpouseLabel).Count(), @@ -1656,22 +1426,22 @@ func (uuo *UserUpdateOne) gremlin(id string) *dsl.Traversal { test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.SpouseLabel, id)), }) } - for id := range uuo.removedChildren { + for _, id := range uuo.mutation.RemovedChildrenIDs() { tr := rv.Clone().InE(user.ParentLabel).Where(__.OtherV().HasID(id)).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.children { + for _, id := range uuo.mutation.ChildrenIDs() { v.AddE(user.ParentLabel).From(g.V(id)).InV() constraints = append(constraints, &constraint{ pred: g.E().HasLabel(user.ParentLabel).OutV().HasID(id).Count(), test: __.Is(p.NEQ(0)).Constant(NewErrUniqueEdge(user.Label, user.ParentLabel, id)), }) } - if uuo.clearedParent { + if uuo.mutation.ParentCleared() { tr := rv.Clone().OutE(user.ParentLabel).Drop().Iterate() trs = append(trs, tr) } - for id := range uuo.parent { + for _, id := range uuo.mutation.ParentIDs() { v.AddE(user.ParentLabel).To(g.V(id)).OutV() } v.ValueMap(true) diff --git a/entc/integration/hooks/ent/card.go b/entc/integration/hooks/ent/card.go new file mode 100644 index 000000000..62d99f696 --- /dev/null +++ b/entc/integration/hooks/ent/card.go @@ -0,0 +1,160 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" +) + +// Card is the model entity for the Card schema. +type Card struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // Number holds the value of the "number" field. + Number string `json:"number,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the CardQuery when eager-loading is set. + Edges CardEdges `json:"edges"` + user_cards *int +} + +// CardEdges holds the relations/edges for other nodes in the graph. +type CardEdges struct { + // Owner holds the value of the owner edge. + Owner *User + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// OwnerOrErr returns the Owner value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e CardEdges) OwnerOrErr() (*User, error) { + if e.loadedTypes[0] { + if e.Owner == nil { + // The edge owner was loaded in eager-loading, + // but was not found. + return nil, &NotFoundError{label: user.Label} + } + return e.Owner, nil + } + return nil, &NotLoadedError{edge: "owner"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Card) scanValues() []interface{} { + return []interface{}{ + &sql.NullInt64{}, // id + &sql.NullString{}, // number + &sql.NullString{}, // name + &sql.NullTime{}, // created_at + } +} + +// fkValues returns the types for scanning foreign-keys values from sql.Rows. +func (*Card) fkValues() []interface{} { + return []interface{}{ + &sql.NullInt64{}, // user_cards + } +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Card fields. +func (c *Card) assignValues(values ...interface{}) error { + if m, n := len(values), len(card.Columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + value, ok := values[0].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + c.ID = int(value.Int64) + values = values[1:] + if value, ok := values[0].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field number", values[0]) + } else if value.Valid { + c.Number = value.String + } + if value, ok := values[1].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[1]) + } else if value.Valid { + c.Name = value.String + } + if value, ok := values[2].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[2]) + } else if value.Valid { + c.CreatedAt = value.Time + } + values = values[3:] + if len(values) == len(card.ForeignKeys) { + if value, ok := values[0].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for edge-field user_cards", value) + } else if value.Valid { + c.user_cards = new(int) + *c.user_cards = int(value.Int64) + } + } + return nil +} + +// QueryOwner queries the owner edge of the Card. +func (c *Card) QueryOwner() *UserQuery { + return (&CardClient{config: c.config}).QueryOwner(c) +} + +// Update returns a builder for updating this Card. +// Note that, you need to call Card.Unwrap() before calling this method, if this Card +// was returned from a transaction, and the transaction was committed or rolled back. +func (c *Card) Update() *CardUpdateOne { + return (&CardClient{config: c.config}).UpdateOne(c) +} + +// Unwrap unwraps the entity that was returned from a transaction after it was closed, +// so that all next queries will be executed through the driver which created the transaction. +func (c *Card) Unwrap() *Card { + tx, ok := c.config.driver.(*txDriver) + if !ok { + panic("ent: Card is not a transactional entity") + } + c.config.driver = tx.drv + return c +} + +// String implements the fmt.Stringer. +func (c *Card) String() string { + var builder strings.Builder + builder.WriteString("Card(") + builder.WriteString(fmt.Sprintf("id=%v", c.ID)) + builder.WriteString(", number=") + builder.WriteString(c.Number) + builder.WriteString(", name=") + builder.WriteString(c.Name) + builder.WriteString(", created_at=") + builder.WriteString(c.CreatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// Cards is a parsable slice of Card. +type Cards []*Card + +func (c Cards) config(cfg config) { + for _i := range c { + c[_i].config = cfg + } +} diff --git a/entc/integration/hooks/ent/card/card.go b/entc/integration/hooks/ent/card/card.go new file mode 100644 index 000000000..214a9045c --- /dev/null +++ b/entc/integration/hooks/ent/card/card.go @@ -0,0 +1,65 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package card + +import ( + "time" + + "github.com/facebookincubator/ent" +) + +const ( + // Label holds the string label denoting the card type in the database. + Label = "card" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" // FieldNumber holds the string denoting the number vertex property in the database. + FieldNumber = "number" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldCreatedAt holds the string denoting the created_at vertex property in the database. + FieldCreatedAt = "created_at" + + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + + // Table holds the table name of the card in the database. + Table = "cards" + // OwnerTable is the table the holds the owner relation/edge. + OwnerTable = "cards" + // OwnerInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + OwnerInverseTable = "users" + // OwnerColumn is the table column denoting the owner relation/edge. + OwnerColumn = "user_cards" +) + +// Columns holds all SQL columns for card fields. +var Columns = []string{ + FieldID, + FieldNumber, + FieldName, + FieldCreatedAt, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the Card type. +var ForeignKeys = []string{ + "user_cards", +} + +// Note that the variables below are initialized by the runtime +// package on the initialization of the application. Therefore, +// it should be imported in the main as follows: +// +// import _ "github.com/facebookincubator/ent/entc/integration/hooks/ent/runtime" +// +var ( + Hooks [2]ent.Hook + // DefaultNumber holds the default value on creation for the number field. + DefaultNumber string + // NumberValidator is a validator for the "number" field. It is called by the builders before save. + NumberValidator func(string) error + // DefaultCreatedAt holds the default value on creation for the created_at field. + DefaultCreatedAt func() time.Time +) diff --git a/entc/integration/hooks/ent/card/where.go b/entc/integration/hooks/ent/card/where.go new file mode 100644 index 000000000..c2dded62e --- /dev/null +++ b/entc/integration/hooks/ent/card/where.go @@ -0,0 +1,491 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package card + +import ( + "time" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" +) + +// ID filters vertices based on their identifier. +func ID(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldID), id)) + }) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.In(s.C(FieldID), v...)) + }) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.NotIn(s.C(FieldID), v...)) + }) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldID), id)) + }) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldID), id)) + }) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldID), id)) + }) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldID), id)) + }) +} + +// Number applies equality check predicate on the "number" field. It's identical to NumberEQ. +func Number(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldNumber), v)) + }) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldName), v)) + }) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldCreatedAt), v)) + }) +} + +// NumberEQ applies the EQ predicate on the "number" field. +func NumberEQ(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldNumber), v)) + }) +} + +// NumberNEQ applies the NEQ predicate on the "number" field. +func NumberNEQ(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldNumber), v)) + }) +} + +// NumberIn applies the In predicate on the "number" field. +func NumberIn(vs ...string) predicate.Card { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldNumber), v...)) + }) +} + +// NumberNotIn applies the NotIn predicate on the "number" field. +func NumberNotIn(vs ...string) predicate.Card { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldNumber), v...)) + }) +} + +// NumberGT applies the GT predicate on the "number" field. +func NumberGT(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldNumber), v)) + }) +} + +// NumberGTE applies the GTE predicate on the "number" field. +func NumberGTE(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldNumber), v)) + }) +} + +// NumberLT applies the LT predicate on the "number" field. +func NumberLT(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldNumber), v)) + }) +} + +// NumberLTE applies the LTE predicate on the "number" field. +func NumberLTE(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldNumber), v)) + }) +} + +// NumberContains applies the Contains predicate on the "number" field. +func NumberContains(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.Contains(s.C(FieldNumber), v)) + }) +} + +// NumberHasPrefix applies the HasPrefix predicate on the "number" field. +func NumberHasPrefix(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.HasPrefix(s.C(FieldNumber), v)) + }) +} + +// NumberHasSuffix applies the HasSuffix predicate on the "number" field. +func NumberHasSuffix(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.HasSuffix(s.C(FieldNumber), v)) + }) +} + +// NumberEqualFold applies the EqualFold predicate on the "number" field. +func NumberEqualFold(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EqualFold(s.C(FieldNumber), v)) + }) +} + +// NumberContainsFold applies the ContainsFold predicate on the "number" field. +func NumberContainsFold(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.ContainsFold(s.C(FieldNumber), v)) + }) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldName), v)) + }) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldName), v)) + }) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.Card { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldName), v...)) + }) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.Card { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldName), v...)) + }) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldName), v)) + }) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldName), v)) + }) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldName), v)) + }) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldName), v)) + }) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.Contains(s.C(FieldName), v)) + }) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.HasPrefix(s.C(FieldName), v)) + }) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.HasSuffix(s.C(FieldName), v)) + }) +} + +// NameIsNil applies the IsNil predicate on the "name" field. +func NameIsNil() predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldName))) + }) +} + +// NameNotNil applies the NotNil predicate on the "name" field. +func NameNotNil() predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldName))) + }) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EqualFold(s.C(FieldName), v)) + }) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.ContainsFold(s.C(FieldName), v)) + }) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.Card { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldCreatedAt), v...)) + }) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.Card { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Card(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldCreatedAt), v...)) + }) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldCreatedAt), v)) + }) +} + +// HasOwner applies the HasEdge predicate on the "owner" edge. +func HasOwner() predicate.Card { + return predicate.Card(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(OwnerTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates). +func HasOwnerWith(preds ...predicate.User) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(OwnerInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups list of predicates with the AND operator between them. +func And(predicates ...predicate.Card) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for _, p := range predicates { + p(s1) + } + s.Where(s1.P()) + }) +} + +// Or groups list of predicates with the OR operator between them. +func Or(predicates ...predicate.Card) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for i, p := range predicates { + if i > 0 { + s1.Or() + } + p(s1) + } + s.Where(s1.P()) + }) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Card) predicate.Card { + return predicate.Card(func(s *sql.Selector) { + p(s.Not()) + }) +} diff --git a/entc/integration/hooks/ent/card_create.go b/entc/integration/hooks/ent/card_create.go new file mode 100644 index 000000000..b921368fc --- /dev/null +++ b/entc/integration/hooks/ent/card_create.go @@ -0,0 +1,201 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "time" + + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// CardCreate is the builder for creating a Card entity. +type CardCreate struct { + config + mutation *CardMutation + hooks []Hook +} + +// SetNumber sets the number field. +func (cc *CardCreate) SetNumber(s string) *CardCreate { + cc.mutation.SetNumber(s) + return cc +} + +// SetNillableNumber sets the number field if the given value is not nil. +func (cc *CardCreate) SetNillableNumber(s *string) *CardCreate { + if s != nil { + cc.SetNumber(*s) + } + return cc +} + +// SetName sets the name field. +func (cc *CardCreate) SetName(s string) *CardCreate { + cc.mutation.SetName(s) + return cc +} + +// SetNillableName sets the name field if the given value is not nil. +func (cc *CardCreate) SetNillableName(s *string) *CardCreate { + if s != nil { + cc.SetName(*s) + } + return cc +} + +// SetCreatedAt sets the created_at field. +func (cc *CardCreate) SetCreatedAt(t time.Time) *CardCreate { + cc.mutation.SetCreatedAt(t) + return cc +} + +// SetNillableCreatedAt sets the created_at field if the given value is not nil. +func (cc *CardCreate) SetNillableCreatedAt(t *time.Time) *CardCreate { + if t != nil { + cc.SetCreatedAt(*t) + } + return cc +} + +// SetOwnerID sets the owner edge to User by id. +func (cc *CardCreate) SetOwnerID(id int) *CardCreate { + cc.mutation.SetOwnerID(id) + return cc +} + +// SetNillableOwnerID sets the owner edge to User by id if the given value is not nil. +func (cc *CardCreate) SetNillableOwnerID(id *int) *CardCreate { + if id != nil { + cc = cc.SetOwnerID(*id) + } + return cc +} + +// SetOwner sets the owner edge to User. +func (cc *CardCreate) SetOwner(u *User) *CardCreate { + return cc.SetOwnerID(u.ID) +} + +// Save creates the Card in the database. +func (cc *CardCreate) Save(ctx context.Context) (*Card, error) { + if _, ok := cc.mutation.Number(); !ok { + v := card.DefaultNumber + cc.mutation.SetNumber(v) + } + if v, ok := cc.mutation.Number(); ok { + if err := card.NumberValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"number\": %v", err) + } + } + if _, ok := cc.mutation.CreatedAt(); !ok { + v := card.DefaultCreatedAt() + cc.mutation.SetCreatedAt(v) + } + var ( + err error + node *Card + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX calls Save and panics if Save returns an error. +func (cc *CardCreate) SaveX(ctx context.Context) *Card { + v, err := cc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { + var ( + c = &Card{config: cc.config} + _spec = &sqlgraph.CreateSpec{ + Table: card.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + } + ) + if value, ok := cc.mutation.Number(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: card.FieldNumber, + }) + c.Number = value + } + if value, ok := cc.mutation.Name(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: card.FieldName, + }) + c.Name = value + } + if value, ok := cc.mutation.CreatedAt(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: card.FieldCreatedAt, + }) + c.CreatedAt = value + } + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: card.OwnerTable, + Columns: []string{card.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if err := sqlgraph.CreateNode(ctx, cc.driver, _spec); err != nil { + if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return nil, err + } + id := _spec.ID.Value.(int64) + c.ID = int(id) + return c, nil +} diff --git a/entc/integration/hooks/ent/card_delete.go b/entc/integration/hooks/ent/card_delete.go new file mode 100644 index 000000000..0e54ed971 --- /dev/null +++ b/entc/integration/hooks/ent/card_delete.go @@ -0,0 +1,112 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" + "github.com/facebookincubator/ent/schema/field" +) + +// CardDelete is the builder for deleting a Card entity. +type CardDelete struct { + config + hooks []Hook + mutation *CardMutation + predicates []predicate.Card +} + +// Where adds a new predicate to the delete builder. +func (cd *CardDelete) Where(ps ...predicate.Card) *CardDelete { + cd.predicates = append(cd.predicates, ps...) + return cd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (cd *CardDelete) Exec(ctx context.Context) (int, error) { + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// ExecX is like Exec, but panics if an error occurs. +func (cd *CardDelete) ExecX(ctx context.Context) int { + n, err := cd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (cd *CardDelete) sqlExec(ctx context.Context) (int, error) { + _spec := &sqlgraph.DeleteSpec{ + Node: &sqlgraph.NodeSpec{ + Table: card.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + if ps := cd.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return sqlgraph.DeleteNodes(ctx, cd.driver, _spec) +} + +// CardDeleteOne is the builder for deleting a single Card entity. +type CardDeleteOne struct { + cd *CardDelete +} + +// Exec executes the deletion query. +func (cdo *CardDeleteOne) Exec(ctx context.Context) error { + n, err := cdo.cd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{card.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (cdo *CardDeleteOne) ExecX(ctx context.Context) { + cdo.cd.ExecX(ctx) +} diff --git a/entc/integration/hooks/ent/card_query.go b/entc/integration/hooks/ent/card_query.go new file mode 100644 index 000000000..21c8ca32a --- /dev/null +++ b/entc/integration/hooks/ent/card_query.go @@ -0,0 +1,685 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "math" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// CardQuery is the builder for querying Card entities. +type CardQuery struct { + config + limit *int + offset *int + order []Order + unique []string + predicates []predicate.Card + // eager-loading edges. + withOwner *UserQuery + withFKs bool + // intermediate query. + sql *sql.Selector +} + +// Where adds a new predicate for the builder. +func (cq *CardQuery) Where(ps ...predicate.Card) *CardQuery { + cq.predicates = append(cq.predicates, ps...) + return cq +} + +// Limit adds a limit step to the query. +func (cq *CardQuery) Limit(limit int) *CardQuery { + cq.limit = &limit + return cq +} + +// Offset adds an offset step to the query. +func (cq *CardQuery) Offset(offset int) *CardQuery { + cq.offset = &offset + return cq +} + +// Order adds an order step to the query. +func (cq *CardQuery) Order(o ...Order) *CardQuery { + cq.order = append(cq.order, o...) + return cq +} + +// QueryOwner chains the current query on the owner edge. +func (cq *CardQuery) QueryOwner() *UserQuery { + query := &UserQuery{config: cq.config} + step := sqlgraph.NewStep( + sqlgraph.From(card.Table, card.FieldID, cq.sqlQuery()), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, card.OwnerTable, card.OwnerColumn), + ) + query.sql = sqlgraph.SetNeighbors(cq.driver.Dialect(), step) + return query +} + +// First returns the first Card entity in the query. Returns *NotFoundError when no card was found. +func (cq *CardQuery) First(ctx context.Context) (*Card, error) { + cs, err := cq.Limit(1).All(ctx) + if err != nil { + return nil, err + } + if len(cs) == 0 { + return nil, &NotFoundError{card.Label} + } + return cs[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (cq *CardQuery) FirstX(ctx context.Context) *Card { + c, err := cq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return c +} + +// FirstID returns the first Card id in the query. Returns *NotFoundError when no id was found. +func (cq *CardQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = cq.Limit(1).IDs(ctx); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{card.Label} + return + } + return ids[0], nil +} + +// FirstXID is like FirstID, but panics if an error occurs. +func (cq *CardQuery) FirstXID(ctx context.Context) int { + id, err := cq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns the only Card entity in the query, returns an error if not exactly one entity was returned. +func (cq *CardQuery) Only(ctx context.Context) (*Card, error) { + cs, err := cq.Limit(2).All(ctx) + if err != nil { + return nil, err + } + switch len(cs) { + case 1: + return cs[0], nil + case 0: + return nil, &NotFoundError{card.Label} + default: + return nil, &NotSingularError{card.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (cq *CardQuery) OnlyX(ctx context.Context) *Card { + c, err := cq.Only(ctx) + if err != nil { + panic(err) + } + return c +} + +// OnlyID returns the only Card id in the query, returns an error if not exactly one id was returned. +func (cq *CardQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = cq.Limit(2).IDs(ctx); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{card.Label} + default: + err = &NotSingularError{card.Label} + } + return +} + +// OnlyXID is like OnlyID, but panics if an error occurs. +func (cq *CardQuery) OnlyXID(ctx context.Context) int { + id, err := cq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Cards. +func (cq *CardQuery) All(ctx context.Context) ([]*Card, error) { + return cq.sqlAll(ctx) +} + +// AllX is like All, but panics if an error occurs. +func (cq *CardQuery) AllX(ctx context.Context) []*Card { + cs, err := cq.All(ctx) + if err != nil { + panic(err) + } + return cs +} + +// IDs executes the query and returns a list of Card ids. +func (cq *CardQuery) IDs(ctx context.Context) ([]int, error) { + var ids []int + if err := cq.Select(card.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (cq *CardQuery) IDsX(ctx context.Context) []int { + ids, err := cq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (cq *CardQuery) Count(ctx context.Context) (int, error) { + return cq.sqlCount(ctx) +} + +// CountX is like Count, but panics if an error occurs. +func (cq *CardQuery) CountX(ctx context.Context) int { + count, err := cq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (cq *CardQuery) Exist(ctx context.Context) (bool, error) { + return cq.sqlExist(ctx) +} + +// ExistX is like Exist, but panics if an error occurs. +func (cq *CardQuery) ExistX(ctx context.Context) bool { + exist, err := cq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the query builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (cq *CardQuery) Clone() *CardQuery { + return &CardQuery{ + config: cq.config, + limit: cq.limit, + offset: cq.offset, + order: append([]Order{}, cq.order...), + unique: append([]string{}, cq.unique...), + predicates: append([]predicate.Card{}, cq.predicates...), + // clone intermediate query. + sql: cq.sql.Clone(), + } +} + +// WithOwner tells the query-builder to eager-loads the nodes that are connected to +// the "owner" edge. The optional arguments used to configure the query builder of the edge. +func (cq *CardQuery) WithOwner(opts ...func(*UserQuery)) *CardQuery { + query := &UserQuery{config: cq.config} + for _, opt := range opts { + opt(query) + } + cq.withOwner = query + return cq +} + +// GroupBy used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Number string `json:"number,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Card.Query(). +// GroupBy(card.FieldNumber). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +// +func (cq *CardQuery) GroupBy(field string, fields ...string) *CardGroupBy { + group := &CardGroupBy{config: cq.config} + group.fields = append([]string{field}, fields...) + group.sql = cq.sqlQuery() + return group +} + +// Select one or more fields from the given query. +// +// Example: +// +// var v []struct { +// Number string `json:"number,omitempty"` +// } +// +// client.Card.Query(). +// Select(card.FieldNumber). +// Scan(ctx, &v) +// +func (cq *CardQuery) Select(field string, fields ...string) *CardSelect { + selector := &CardSelect{config: cq.config} + selector.fields = append([]string{field}, fields...) + selector.sql = cq.sqlQuery() + return selector +} + +func (cq *CardQuery) sqlAll(ctx context.Context) ([]*Card, error) { + var ( + nodes = []*Card{} + withFKs = cq.withFKs + _spec = cq.querySpec() + loadedTypes = [1]bool{ + cq.withOwner != nil, + } + ) + if cq.withOwner != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, card.ForeignKeys...) + } + _spec.ScanValues = func() []interface{} { + node := &Card{config: cq.config} + nodes = append(nodes, node) + values := node.scanValues() + if withFKs { + values = append(values, node.fkValues()...) + } + return values + } + _spec.Assign = func(values ...interface{}) error { + if len(nodes) == 0 { + return fmt.Errorf("ent: Assign called without calling ScanValues") + } + node := nodes[len(nodes)-1] + node.Edges.loadedTypes = loadedTypes + return node.assignValues(values...) + } + if err := sqlgraph.QueryNodes(ctx, cq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + + if query := cq.withOwner; query != nil { + ids := make([]int, 0, len(nodes)) + nodeids := make(map[int][]*Card) + for i := range nodes { + if fk := nodes[i].user_cards; fk != nil { + ids = append(ids, *fk) + nodeids[*fk] = append(nodeids[*fk], nodes[i]) + } + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "user_cards" returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.Owner = n + } + } + } + + return nodes, nil +} + +func (cq *CardQuery) sqlCount(ctx context.Context) (int, error) { + _spec := cq.querySpec() + return sqlgraph.CountNodes(ctx, cq.driver, _spec) +} + +func (cq *CardQuery) sqlExist(ctx context.Context) (bool, error) { + n, err := cq.sqlCount(ctx) + if err != nil { + return false, fmt.Errorf("ent: check existence: %v", err) + } + return n > 0, nil +} + +func (cq *CardQuery) querySpec() *sqlgraph.QuerySpec { + _spec := &sqlgraph.QuerySpec{ + Node: &sqlgraph.NodeSpec{ + Table: card.Table, + Columns: card.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + From: cq.sql, + Unique: true, + } + if ps := cq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := cq.limit; limit != nil { + _spec.Limit = *limit + } + if offset := cq.offset; offset != nil { + _spec.Offset = *offset + } + if ps := cq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (cq *CardQuery) sqlQuery() *sql.Selector { + builder := sql.Dialect(cq.driver.Dialect()) + t1 := builder.Table(card.Table) + selector := builder.Select(t1.Columns(card.Columns...)...).From(t1) + if cq.sql != nil { + selector = cq.sql + selector.Select(selector.Columns(card.Columns...)...) + } + for _, p := range cq.predicates { + p(selector) + } + for _, p := range cq.order { + p(selector) + } + if offset := cq.offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := cq.limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// CardGroupBy is the builder for group-by Card entities. +type CardGroupBy struct { + config + fields []string + fns []Aggregate + // intermediate query. + sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (cgb *CardGroupBy) Aggregate(fns ...Aggregate) *CardGroupBy { + cgb.fns = append(cgb.fns, fns...) + return cgb +} + +// Scan applies the group-by query and scan the result into the given value. +func (cgb *CardGroupBy) Scan(ctx context.Context, v interface{}) error { + return cgb.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (cgb *CardGroupBy) ScanX(ctx context.Context, v interface{}) { + if err := cgb.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from group-by. It is only allowed when querying group-by with one field. +func (cgb *CardGroupBy) Strings(ctx context.Context) ([]string, error) { + if len(cgb.fields) > 1 { + return nil, errors.New("ent: CardGroupBy.Strings is not achievable when grouping more than 1 field") + } + var v []string + if err := cgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (cgb *CardGroupBy) StringsX(ctx context.Context) []string { + v, err := cgb.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from group-by. It is only allowed when querying group-by with one field. +func (cgb *CardGroupBy) Ints(ctx context.Context) ([]int, error) { + if len(cgb.fields) > 1 { + return nil, errors.New("ent: CardGroupBy.Ints is not achievable when grouping more than 1 field") + } + var v []int + if err := cgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (cgb *CardGroupBy) IntsX(ctx context.Context) []int { + v, err := cgb.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from group-by. It is only allowed when querying group-by with one field. +func (cgb *CardGroupBy) Float64s(ctx context.Context) ([]float64, error) { + if len(cgb.fields) > 1 { + return nil, errors.New("ent: CardGroupBy.Float64s is not achievable when grouping more than 1 field") + } + var v []float64 + if err := cgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (cgb *CardGroupBy) Float64sX(ctx context.Context) []float64 { + v, err := cgb.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from group-by. It is only allowed when querying group-by with one field. +func (cgb *CardGroupBy) Bools(ctx context.Context) ([]bool, error) { + if len(cgb.fields) > 1 { + return nil, errors.New("ent: CardGroupBy.Bools is not achievable when grouping more than 1 field") + } + var v []bool + if err := cgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (cgb *CardGroupBy) BoolsX(ctx context.Context) []bool { + v, err := cgb.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (cgb *CardGroupBy) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := cgb.sqlQuery().Query() + if err := cgb.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (cgb *CardGroupBy) sqlQuery() *sql.Selector { + selector := cgb.sql + columns := make([]string, 0, len(cgb.fields)+len(cgb.fns)) + columns = append(columns, cgb.fields...) + for _, fn := range cgb.fns { + columns = append(columns, fn(selector)) + } + return selector.Select(columns...).GroupBy(cgb.fields...) +} + +// CardSelect is the builder for select fields of Card entities. +type CardSelect struct { + config + fields []string + // intermediate queries. + sql *sql.Selector +} + +// Scan applies the selector query and scan the result into the given value. +func (cs *CardSelect) Scan(ctx context.Context, v interface{}) error { + return cs.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (cs *CardSelect) ScanX(ctx context.Context, v interface{}) { + if err := cs.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from selector. It is only allowed when selecting one field. +func (cs *CardSelect) Strings(ctx context.Context) ([]string, error) { + if len(cs.fields) > 1 { + return nil, errors.New("ent: CardSelect.Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := cs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (cs *CardSelect) StringsX(ctx context.Context) []string { + v, err := cs.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from selector. It is only allowed when selecting one field. +func (cs *CardSelect) Ints(ctx context.Context) ([]int, error) { + if len(cs.fields) > 1 { + return nil, errors.New("ent: CardSelect.Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := cs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (cs *CardSelect) IntsX(ctx context.Context) []int { + v, err := cs.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from selector. It is only allowed when selecting one field. +func (cs *CardSelect) Float64s(ctx context.Context) ([]float64, error) { + if len(cs.fields) > 1 { + return nil, errors.New("ent: CardSelect.Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := cs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (cs *CardSelect) Float64sX(ctx context.Context) []float64 { + v, err := cs.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from selector. It is only allowed when selecting one field. +func (cs *CardSelect) Bools(ctx context.Context) ([]bool, error) { + if len(cs.fields) > 1 { + return nil, errors.New("ent: CardSelect.Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := cs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (cs *CardSelect) BoolsX(ctx context.Context) []bool { + v, err := cs.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (cs *CardSelect) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := cs.sqlQuery().Query() + if err := cs.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (cs *CardSelect) sqlQuery() sql.Querier { + selector := cs.sql + selector.Select(selector.Columns(cs.fields...)...) + return selector +} diff --git a/entc/integration/hooks/ent/card_update.go b/entc/integration/hooks/ent/card_update.go new file mode 100644 index 000000000..452eebadb --- /dev/null +++ b/entc/integration/hooks/ent/card_update.go @@ -0,0 +1,430 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "time" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// CardUpdate is the builder for updating Card entities. +type CardUpdate struct { + config + hooks []Hook + mutation *CardMutation + predicates []predicate.Card +} + +// Where adds a new predicate for the builder. +func (cu *CardUpdate) Where(ps ...predicate.Card) *CardUpdate { + cu.predicates = append(cu.predicates, ps...) + return cu +} + +// SetName sets the name field. +func (cu *CardUpdate) SetName(s string) *CardUpdate { + cu.mutation.SetName(s) + return cu +} + +// SetNillableName sets the name field if the given value is not nil. +func (cu *CardUpdate) SetNillableName(s *string) *CardUpdate { + if s != nil { + cu.SetName(*s) + } + return cu +} + +// ClearName clears the value of name. +func (cu *CardUpdate) ClearName() *CardUpdate { + cu.mutation.ClearName() + return cu +} + +// SetCreatedAt sets the created_at field. +func (cu *CardUpdate) SetCreatedAt(t time.Time) *CardUpdate { + cu.mutation.SetCreatedAt(t) + return cu +} + +// SetNillableCreatedAt sets the created_at field if the given value is not nil. +func (cu *CardUpdate) SetNillableCreatedAt(t *time.Time) *CardUpdate { + if t != nil { + cu.SetCreatedAt(*t) + } + return cu +} + +// SetOwnerID sets the owner edge to User by id. +func (cu *CardUpdate) SetOwnerID(id int) *CardUpdate { + cu.mutation.SetOwnerID(id) + return cu +} + +// SetNillableOwnerID sets the owner edge to User by id if the given value is not nil. +func (cu *CardUpdate) SetNillableOwnerID(id *int) *CardUpdate { + if id != nil { + cu = cu.SetOwnerID(*id) + } + return cu +} + +// SetOwner sets the owner edge to User. +func (cu *CardUpdate) SetOwner(u *User) *CardUpdate { + return cu.SetOwnerID(u.ID) +} + +// ClearOwner clears the owner edge to User. +func (cu *CardUpdate) ClearOwner() *CardUpdate { + cu.mutation.ClearOwner() + return cu +} + +// Save executes the query and returns the number of rows/vertices matched by this operation. +func (cu *CardUpdate) Save(ctx context.Context) (int, error) { + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// SaveX is like Save, but panics if an error occurs. +func (cu *CardUpdate) SaveX(ctx context.Context) int { + affected, err := cu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (cu *CardUpdate) Exec(ctx context.Context) error { + _, err := cu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (cu *CardUpdate) ExecX(ctx context.Context) { + if err := cu.Exec(ctx); err != nil { + panic(err) + } +} + +func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: card.Table, + Columns: card.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + if ps := cu.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := cu.mutation.Name(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: card.FieldName, + }) + } + if cu.mutation.NameCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Column: card.FieldName, + }) + } + if value, ok := cu.mutation.CreatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: card.FieldCreatedAt, + }) + } + if cu.mutation.OwnerCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: card.OwnerTable, + Columns: []string{card.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: card.OwnerTable, + Columns: []string{card.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, cu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{card.Label} + } else if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return 0, err + } + return n, nil +} + +// CardUpdateOne is the builder for updating a single Card entity. +type CardUpdateOne struct { + config + hooks []Hook + mutation *CardMutation +} + +// SetName sets the name field. +func (cuo *CardUpdateOne) SetName(s string) *CardUpdateOne { + cuo.mutation.SetName(s) + return cuo +} + +// SetNillableName sets the name field if the given value is not nil. +func (cuo *CardUpdateOne) SetNillableName(s *string) *CardUpdateOne { + if s != nil { + cuo.SetName(*s) + } + return cuo +} + +// ClearName clears the value of name. +func (cuo *CardUpdateOne) ClearName() *CardUpdateOne { + cuo.mutation.ClearName() + return cuo +} + +// SetCreatedAt sets the created_at field. +func (cuo *CardUpdateOne) SetCreatedAt(t time.Time) *CardUpdateOne { + cuo.mutation.SetCreatedAt(t) + return cuo +} + +// SetNillableCreatedAt sets the created_at field if the given value is not nil. +func (cuo *CardUpdateOne) SetNillableCreatedAt(t *time.Time) *CardUpdateOne { + if t != nil { + cuo.SetCreatedAt(*t) + } + return cuo +} + +// SetOwnerID sets the owner edge to User by id. +func (cuo *CardUpdateOne) SetOwnerID(id int) *CardUpdateOne { + cuo.mutation.SetOwnerID(id) + return cuo +} + +// SetNillableOwnerID sets the owner edge to User by id if the given value is not nil. +func (cuo *CardUpdateOne) SetNillableOwnerID(id *int) *CardUpdateOne { + if id != nil { + cuo = cuo.SetOwnerID(*id) + } + return cuo +} + +// SetOwner sets the owner edge to User. +func (cuo *CardUpdateOne) SetOwner(u *User) *CardUpdateOne { + return cuo.SetOwnerID(u.ID) +} + +// ClearOwner clears the owner edge to User. +func (cuo *CardUpdateOne) ClearOwner() *CardUpdateOne { + cuo.mutation.ClearOwner() + return cuo +} + +// Save executes the query and returns the updated entity. +func (cuo *CardUpdateOne) Save(ctx context.Context) (*Card, error) { + + var ( + err error + node *Card + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX is like Save, but panics if an error occurs. +func (cuo *CardUpdateOne) SaveX(ctx context.Context) *Card { + c, err := cuo.Save(ctx) + if err != nil { + panic(err) + } + return c +} + +// Exec executes the query on the entity. +func (cuo *CardUpdateOne) Exec(ctx context.Context) error { + _, err := cuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (cuo *CardUpdateOne) ExecX(ctx context.Context) { + if err := cuo.Exec(ctx); err != nil { + panic(err) + } +} + +func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: card.Table, + Columns: card.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Card.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.Name(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: card.FieldName, + }) + } + if cuo.mutation.NameCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Column: card.FieldName, + }) + } + if value, ok := cuo.mutation.CreatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: card.FieldCreatedAt, + }) + } + if cuo.mutation.OwnerCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: card.OwnerTable, + Columns: []string{card.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: card.OwnerTable, + Columns: []string{card.OwnerColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + c = &Card{config: cuo.config} + _spec.Assign = c.assignValues + _spec.ScanValues = c.scanValues() + if err = sqlgraph.UpdateNode(ctx, cuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{card.Label} + } else if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return nil, err + } + return c, nil +} diff --git a/entc/integration/hooks/ent/client.go b/entc/integration/hooks/ent/client.go new file mode 100644 index 000000000..135da8042 --- /dev/null +++ b/entc/integration/hooks/ent/client.go @@ -0,0 +1,333 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "log" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent/migrate" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" +) + +// Client is the client that holds all ent builders. +type Client struct { + config + // Schema is the client for creating, migrating and dropping schema. + Schema *migrate.Schema + // Card is the client for interacting with the Card builders. + Card *CardClient + // User is the client for interacting with the User builders. + User *UserClient +} + +// NewClient creates a new client configured with the given options. +func NewClient(opts ...Option) *Client { + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Card = NewCardClient(c.config) + c.User = NewUserClient(c.config) +} + +// Open opens a connection to the database specified by the driver name and a +// driver-specific data source name, and returns a new client attached to it. +// Optional parameters can be added for configuring the client. +func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { + switch driverName { + case dialect.MySQL, dialect.Postgres, dialect.SQLite: + drv, err := sql.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + return NewClient(append(options, Driver(drv))...), nil + default: + return nil, fmt.Errorf("unsupported driver: %q", driverName) + } +} + +// Tx returns a new transactional client. +func (c *Client) Tx(ctx context.Context) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") + } + tx, err := newTx(ctx, c.driver) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %v", err) + } + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} + return &Tx{ + config: cfg, + Card: NewCardClient(cfg), + User: NewUserClient(cfg), + }, nil +} + +// Debug returns a new debug-client. It's used to get verbose logging on specific operations. +// +// client.Debug(). +// Card. +// Query(). +// Count(ctx) +// +func (c *Client) Debug() *Client { + if c.debug { + return c + } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client +} + +// Close closes the database connection and prevents new queries from starting. +func (c *Client) Close() error { + return c.driver.Close() +} + +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Card.Use(hooks...) + c.User.Use(hooks...) +} + +// CardClient is a client for the Card schema. +type CardClient struct { + config +} + +// NewCardClient returns a client for the Card from the given config. +func NewCardClient(c config) *CardClient { + return &CardClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `card.Hooks(f(g(h())))`. +func (c *CardClient) Use(hooks ...Hook) { + c.hooks.Card = append(c.hooks.Card, hooks...) +} + +// Create returns a create builder for Card. +func (c *CardClient) Create() *CardCreate { + mutation := newCardMutation(c.config, OpCreate) + return &CardCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Update returns an update builder for Card. +func (c *CardClient) Update() *CardUpdate { + mutation := newCardMutation(c.config, OpUpdate) + return &CardUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *CardClient) UpdateOne(ca *Card) *CardUpdateOne { + return c.UpdateOneID(ca.ID) +} + +// UpdateOneID returns an update builder for the given id. +func (c *CardClient) UpdateOneID(id int) *CardUpdateOne { + mutation := newCardMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CardUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Card. +func (c *CardClient) Delete() *CardDelete { + mutation := newCardMutation(c.config, OpDelete) + return &CardDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a delete builder for the given entity. +func (c *CardClient) DeleteOne(ca *Card) *CardDeleteOne { + return c.DeleteOneID(ca.ID) +} + +// DeleteOneID returns a delete builder for the given id. +func (c *CardClient) DeleteOneID(id int) *CardDeleteOne { + builder := c.Delete().Where(card.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CardDeleteOne{builder} +} + +// Create returns a query builder for Card. +func (c *CardClient) Query() *CardQuery { + return &CardQuery{config: c.config} +} + +// Get returns a Card entity by its id. +func (c *CardClient) Get(ctx context.Context, id int) (*Card, error) { + return c.Query().Where(card.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *CardClient) GetX(ctx context.Context, id int) *Card { + ca, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return ca +} + +// QueryOwner queries the owner edge of a Card. +func (c *CardClient) QueryOwner(ca *Card) *UserQuery { + query := &UserQuery{config: c.config} + id := ca.ID + step := sqlgraph.NewStep( + sqlgraph.From(card.Table, card.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, card.OwnerTable, card.OwnerColumn), + ) + query.sql = sqlgraph.Neighbors(ca.driver.Dialect(), step) + + return query +} + +// Hooks returns the client hooks. +func (c *CardClient) Hooks() []Hook { + hooks := c.hooks.Card + return append(hooks[:len(hooks):len(hooks)], card.Hooks[:]...) +} + +// UserClient is a client for the User schema. +type UserClient struct { + config +} + +// NewUserClient returns a client for the User from the given config. +func NewUserClient(c config) *UserClient { + return &UserClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + +// Create returns a create builder for User. +func (c *UserClient) Create() *UserCreate { + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Update returns an update builder for User. +func (c *UserClient) Update() *UserUpdate { + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { + return c.UpdateOneID(u.ID) +} + +// UpdateOneID returns an update builder for the given id. +func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for User. +func (c *UserClient) Delete() *UserDelete { + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a delete builder for the given entity. +func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { + return c.DeleteOneID(u.ID) +} + +// DeleteOneID returns a delete builder for the given id. +func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} +} + +// Create returns a query builder for User. +func (c *UserClient) Query() *UserQuery { + return &UserQuery{config: c.config} +} + +// Get returns a User entity by its id. +func (c *UserClient) Get(ctx context.Context, id int) (*User, error) { + return c.Query().Where(user.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *UserClient) GetX(ctx context.Context, id int) *User { + u, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return u +} + +// QueryCards queries the cards edge of a User. +func (c *UserClient) QueryCards(u *User) *CardQuery { + query := &CardQuery{config: c.config} + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(card.Table, card.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.CardsTable, user.CardsColumn), + ) + query.sql = sqlgraph.Neighbors(u.driver.Dialect(), step) + + return query +} + +// QueryFriends queries the friends edge of a User. +func (c *UserClient) QueryFriends(u *User) *UserQuery { + query := &UserQuery{config: c.config} + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, user.FriendsTable, user.FriendsPrimaryKey...), + ) + query.sql = sqlgraph.Neighbors(u.driver.Dialect(), step) + + return query +} + +// QueryBestFriend queries the best_friend edge of a User. +func (c *UserClient) QueryBestFriend(u *User) *UserQuery { + query := &UserQuery{config: c.config} + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, user.BestFriendTable, user.BestFriendColumn), + ) + query.sql = sqlgraph.Neighbors(u.driver.Dialect(), step) + + return query +} + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/hooks/ent/config.go b/entc/integration/hooks/ent/config.go new file mode 100644 index 000000000..9ca84f60e --- /dev/null +++ b/entc/integration/hooks/ent/config.go @@ -0,0 +1,64 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/dialect" +) + +// Option function to configure the client. +type Option func(*config) + +// Config is the configuration for the client and its builder. +type config struct { + // driver used for executing database requests. + driver dialect.Driver + // debug enable a debug logging. + debug bool + // log used for logging on debug mode. + log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Card []ent.Hook + User []ent.Hook +} + +// Options applies the options on the config object. +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } + if c.debug { + c.driver = dialect.Debug(c.driver, c.log) + } +} + +// Debug enables debug logging on the ent.Driver. +func Debug() Option { + return func(c *config) { + c.debug = true + } +} + +// Log sets the logging function for debug mode. +func Log(fn func(...interface{})) Option { + return func(c *config) { + c.log = fn + } +} + +// Driver configures the client driver. +func Driver(driver dialect.Driver) Option { + return func(c *config) { + c.driver = driver + } +} diff --git a/entc/integration/hooks/ent/context.go b/entc/integration/hooks/ent/context.go new file mode 100644 index 000000000..57ecd33b3 --- /dev/null +++ b/entc/integration/hooks/ent/context.go @@ -0,0 +1,24 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" +) + +type contextKey struct{} + +// FromContext returns the Client stored in a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Client { + c, _ := ctx.Value(contextKey{}).(*Client) + return c +} + +// NewContext returns a new context with the given Client attached. +func NewContext(parent context.Context, c *Client) context.Context { + return context.WithValue(parent, contextKey{}, c) +} diff --git a/entc/integration/hooks/ent/ent.go b/entc/integration/hooks/ent/ent.go new file mode 100644 index 000000000..468ee7ba7 --- /dev/null +++ b/entc/integration/hooks/ent/ent.go @@ -0,0 +1,265 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "strings" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "golang.org/x/xerrors" +) + +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + +// Order applies an ordering on either graph traversal or sql selector. +type Order func(*sql.Selector) + +// Asc applies the given fields in ASC order. +func Asc(fields ...string) Order { + return func(s *sql.Selector) { + for _, f := range fields { + s.OrderBy(sql.Asc(f)) + } + } +} + +// Desc applies the given fields in DESC order. +func Desc(fields ...string) Order { + return func(s *sql.Selector) { + for _, f := range fields { + s.OrderBy(sql.Desc(f)) + } + } +} + +// Aggregate applies an aggregation step on the group-by traversal/selector. +type Aggregate func(*sql.Selector) string + +// As is a pseudo aggregation function for renaming another other functions with custom names. For example: +// +// GroupBy(field1, field2). +// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). +// Scan(ctx, &v) +// +func As(fn Aggregate, end string) Aggregate { + return func(s *sql.Selector) string { + return sql.As(fn(s), end) + } +} + +// Count applies the "count" aggregation function on each group. +func Count() Aggregate { + return func(s *sql.Selector) string { + return sql.Count("*") + } +} + +// Max applies the "max" aggregation function on the given field of each group. +func Max(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Max(s.C(field)) + } +} + +// Mean applies the "mean" aggregation function on the given field of each group. +func Mean(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Avg(s.C(field)) + } +} + +// Min applies the "min" aggregation function on the given field of each group. +func Min(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Min(s.C(field)) + } +} + +// Sum applies the "sum" aggregation function on the given field of each group. +func Sum(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Sum(s.C(field)) + } +} + +// NotFoundError returns when trying to fetch a specific entity and it was not found in the database. +type NotFoundError struct { + label string +} + +// Error implements the error interface. +func (e *NotFoundError) Error() string { + return "ent: " + e.label + " not found" +} + +// IsNotFound returns a boolean indicating whether the error is a not found error. +func IsNotFound(err error) bool { + if err == nil { + return false + } + var e *NotFoundError + return xerrors.As(err, &e) +} + +// MaskNotFound masks nor found error. +func MaskNotFound(err error) error { + if IsNotFound(err) { + return nil + } + return err +} + +// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database. +type NotSingularError struct { + label string +} + +// Error implements the error interface. +func (e *NotSingularError) Error() string { + return "ent: " + e.label + " not singular" +} + +// IsNotSingular returns a boolean indicating whether the error is a not singular error. +func IsNotSingular(err error) bool { + if err == nil { + return false + } + var e *NotSingularError + return xerrors.As(err, &e) +} + +// NotLoadedError returns when trying to get a node that was not loaded by the query. +type NotLoadedError struct { + edge string +} + +// Error implements the error interface. +func (e *NotLoadedError) Error() string { + return "ent: " + e.edge + " edge was not loaded" +} + +// IsNotLoaded returns a boolean indicating whether the error is a not loaded error. +func IsNotLoaded(err error) bool { + if err == nil { + return false + } + var e *NotLoadedError + return xerrors.As(err, &e) +} + +// ConstraintError returns when trying to create/update one or more entities and +// one or more of their constraints failed. For example, violation of edge or +// field uniqueness. +type ConstraintError struct { + msg string + wrap error +} + +// Error implements the error interface. +func (e ConstraintError) Error() string { + return "ent: constraint failed: " + e.msg +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ConstraintError) Unwrap() error { + return e.wrap +} + +// IsConstraintError returns a boolean indicating whether the error is a constraint failure. +func IsConstraintError(err error) bool { + if err == nil { + return false + } + var e *ConstraintError + return xerrors.As(err, &e) +} + +func isSQLConstraintError(err error) (*ConstraintError, bool) { + var ( + msg = err.Error() + // error format per dialect. + errors = [...]string{ + "Error 1062", // MySQL 1062 error (ER_DUP_ENTRY). + "UNIQUE constraint failed", // SQLite. + "duplicate key value violates unique constraint", // PostgreSQL. + } + ) + if _, ok := err.(*sqlgraph.ConstraintError); ok { + return &ConstraintError{msg, err}, true + } + for i := range errors { + if strings.Contains(msg, errors[i]) { + return &ConstraintError{msg, err}, true + } + } + return nil, false +} + +// rollback calls to tx.Rollback and wraps the given error with the rollback error if occurred. +func rollback(tx dialect.Tx, err error) error { + if rerr := tx.Rollback(); rerr != nil { + err = fmt.Errorf("%s: %v", err.Error(), rerr) + } + if err, ok := isSQLConstraintError(err); ok { + return err + } + return err +} + +// insertLastID invokes the insert query on the transaction and returns the LastInsertID. +func insertLastID(ctx context.Context, tx dialect.Tx, insert *sql.InsertBuilder) (int64, error) { + query, args := insert.Query() + // PostgreSQL does not support the LastInsertId() method of sql.Result + // on Exec, and should be extracted manually using the `RETURNING` clause. + if insert.Dialect() == dialect.Postgres { + rows := &sql.Rows{} + if err := tx.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, fmt.Errorf("no rows found for query: %v", query) + } + var id int64 + if err := rows.Scan(&id); err != nil { + return 0, err + } + return id, nil + } + // MySQL, SQLite, etc. + var res sql.Result + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, err + } + id, err := res.LastInsertId() + if err != nil { + return 0, err + } + return id, nil +} + +// keys returns the keys/ids from the edge map. +func keys(m map[int]struct{}) []int { + s := make([]int, 0, len(m)) + for id := range m { + s = append(s, id) + } + return s +} diff --git a/entc/integration/hooks/ent/generate.go b/entc/integration/hooks/ent/generate.go new file mode 100644 index 000000000..26146318a --- /dev/null +++ b/entc/integration/hooks/ent/generate.go @@ -0,0 +1,7 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package ent + +//go:generate go run github.com/facebookincubator/ent/cmd/entc generate --header "// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.\n// This source code is licensed under the Apache 2.0 license found\n// in the LICENSE file in the root directory of this source tree.\n\n// Code generated by entc, DO NOT EDIT." ./schema diff --git a/entc/integration/hooks/ent/hook/hook.go b/entc/integration/hooks/ent/hook/hook.go new file mode 100644 index 000000000..abcd7461e --- /dev/null +++ b/entc/integration/hooks/ent/hook/hook.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent" +) + +// The CardFunc type is an adapter to allow the use of ordinary +// function as Card mutator. +type CardFunc func(context.Context, *ent.CardMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CardFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CardMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/hooks/ent/migrate/migrate.go b/entc/integration/hooks/ent/migrate/migrate.go new file mode 100644 index 000000000..1c1cd7a5c --- /dev/null +++ b/entc/integration/hooks/ent/migrate/migrate.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package migrate + +import ( + "context" + "fmt" + "io" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql/schema" +) + +var ( + // WithGlobalUniqueID sets the universal ids options to the migration. + // If this option is enabled, ent migration will allocate a 1<<32 range + // for the ids of each entity (table). + // Note that this option cannot be applied on tables that already exist. + WithGlobalUniqueID = schema.WithGlobalUniqueID + // WithDropColumn sets the drop column option to the migration. + // If this option is enabled, ent migration will drop old columns + // that were used for both fields and edges. This defaults to false. + WithDropColumn = schema.WithDropColumn + // WithDropIndex sets the drop index option to the migration. + // If this option is enabled, ent migration will drop old indexes + // that were defined in the schema. This defaults to false. + // Note that unique constraints are defined using `UNIQUE INDEX`, + // and therefore, it's recommended to enable this option to get more + // flexibility in the schema changes. + WithDropIndex = schema.WithDropIndex + // WithFixture sets the foreign-key renaming option to the migration when upgrading + // ent from v0.1.0 (issue-#285). Defaults to true. + WithFixture = schema.WithFixture +) + +// Schema is the API for creating, migrating and dropping a schema. +type Schema struct { + drv dialect.Driver + universalID bool +} + +// NewSchema creates a new schema client. +func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } + +// Create creates all schema resources. +func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { + migrate, err := schema.NewMigrate(s.drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %v", err) + } + return migrate.Create(ctx, Tables...) +} + +// WriteTo writes the schema changes to w instead of running them against the database. +// +// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { +// log.Fatal(err) +// } +// +func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { + drv := &schema.WriteDriver{ + Writer: w, + Driver: s.drv, + } + migrate, err := schema.NewMigrate(drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %v", err) + } + return migrate.Create(ctx, Tables...) +} diff --git a/entc/integration/hooks/ent/migrate/schema.go b/entc/integration/hooks/ent/migrate/schema.go new file mode 100644 index 000000000..3b13fb9d8 --- /dev/null +++ b/entc/integration/hooks/ent/migrate/schema.go @@ -0,0 +1,99 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package migrate + +import ( + "github.com/facebookincubator/ent/dialect/sql/schema" + "github.com/facebookincubator/ent/schema/field" +) + +var ( + // CardsColumns holds the columns for the "cards" table. + CardsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "number", Type: field.TypeString, Default: "unknown"}, + {Name: "name", Type: field.TypeString, Nullable: true}, + {Name: "created_at", Type: field.TypeTime}, + {Name: "user_cards", Type: field.TypeInt, Nullable: true}, + } + // CardsTable holds the schema information for the "cards" table. + CardsTable = &schema.Table{ + Name: "cards", + Columns: CardsColumns, + PrimaryKey: []*schema.Column{CardsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "cards_users_cards", + Columns: []*schema.Column{CardsColumns[4]}, + + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.SetNull, + }, + }, + } + // UsersColumns holds the columns for the "users" table. + UsersColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "name", Type: field.TypeString}, + {Name: "user_best_friend", Type: field.TypeInt, Unique: true, Nullable: true}, + } + // UsersTable holds the schema information for the "users" table. + UsersTable = &schema.Table{ + Name: "users", + Columns: UsersColumns, + PrimaryKey: []*schema.Column{UsersColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "users_users_best_friend", + Columns: []*schema.Column{UsersColumns[2]}, + + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.SetNull, + }, + }, + } + // UserFriendsColumns holds the columns for the "user_friends" table. + UserFriendsColumns = []*schema.Column{ + {Name: "user_id", Type: field.TypeInt}, + {Name: "friend_id", Type: field.TypeInt}, + } + // UserFriendsTable holds the schema information for the "user_friends" table. + UserFriendsTable = &schema.Table{ + Name: "user_friends", + Columns: UserFriendsColumns, + PrimaryKey: []*schema.Column{UserFriendsColumns[0], UserFriendsColumns[1]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "user_friends_user_id", + Columns: []*schema.Column{UserFriendsColumns[0]}, + + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "user_friends_friend_id", + Columns: []*schema.Column{UserFriendsColumns[1]}, + + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.Cascade, + }, + }, + } + // Tables holds all the tables in the schema. + Tables = []*schema.Table{ + CardsTable, + UsersTable, + UserFriendsTable, + } +) + +func init() { + CardsTable.ForeignKeys[0].RefTable = UsersTable + UsersTable.ForeignKeys[0].RefTable = UsersTable + UserFriendsTable.ForeignKeys[0].RefTable = UsersTable + UserFriendsTable.ForeignKeys[1].RefTable = UsersTable +} diff --git a/entc/integration/hooks/ent/mutation.go b/entc/integration/hooks/ent/mutation.go new file mode 100644 index 000000000..66fe24de6 --- /dev/null +++ b/entc/integration/hooks/ent/mutation.go @@ -0,0 +1,832 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "time" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCard = "Card" + TypeUser = "User" +) + +// CardMutation represents an operation that mutate the Cards +// nodes in the graph. +type CardMutation struct { + config + op Op + typ string + id *int + number *string + name *string + created_at *time.Time + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*CardMutation)(nil) + +// newCardMutation creates new mutation for $n.Name. +func newCardMutation(c config, op Op) *CardMutation { + return &CardMutation{ + config: c, + op: op, + typ: TypeCard, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CardMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CardMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CardMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetNumber sets the number field. +func (m *CardMutation) SetNumber(s string) { + m.number = &s +} + +// Number returns the number value in the mutation. +func (m *CardMutation) Number() (r string, exists bool) { + v := m.number + if v == nil { + return + } + return *v, true +} + +// ResetNumber reset all changes of the number field. +func (m *CardMutation) ResetNumber() { + m.number = nil +} + +// SetName sets the name field. +func (m *CardMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *CardMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ClearName clears the value of name. +func (m *CardMutation) ClearName() { + m.name = nil + m.clearedFields[card.FieldName] = true +} + +// NameCleared returns if the field name was cleared in this mutation. +func (m *CardMutation) NameCleared() bool { + return m.clearedFields[card.FieldName] +} + +// ResetName reset all changes of the name field. +func (m *CardMutation) ResetName() { + m.name = nil + delete(m.clearedFields, card.FieldName) +} + +// SetCreatedAt sets the created_at field. +func (m *CardMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the created_at value in the mutation. +func (m *CardMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// ResetCreatedAt reset all changes of the created_at field. +func (m *CardMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CardMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CardMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CardMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CardMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CardMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CardMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *CardMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Card). +func (m *CardMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CardMutation) Fields() []string { + fields := make([]string, 0, 3) + if m.number != nil { + fields = append(fields, card.FieldNumber) + } + if m.name != nil { + fields = append(fields, card.FieldName) + } + if m.created_at != nil { + fields = append(fields, card.FieldCreatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CardMutation) Field(name string) (ent.Value, bool) { + switch name { + case card.FieldNumber: + return m.Number() + case card.FieldName: + return m.Name() + case card.FieldCreatedAt: + return m.CreatedAt() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) SetField(name string, value ent.Value) error { + switch name { + case card.FieldNumber: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNumber(v) + return nil + case card.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case card.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CardMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CardMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Card numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CardMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[card.FieldName] { + fields = append(fields, card.FieldName) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CardMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CardMutation) ClearField(name string) error { + switch name { + case card.FieldName: + m.ClearName() + return nil + } + return fmt.Errorf("unknown Card nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CardMutation) ResetField(name string) error { + switch name { + case card.FieldNumber: + m.ResetNumber() + return nil + case card.FieldName: + m.ResetName() + return nil + case card.FieldCreatedAt: + m.ResetCreatedAt() + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CardMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, card.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CardMutation) AddedIDs(name string) []ent.Value { + switch name { + case card.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CardMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CardMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CardMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, card.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CardMutation) EdgeCleared(name string) bool { + switch name { + case card.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CardMutation) ClearEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Card unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CardMutation) ResetEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Card edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + cards map[int]struct{} + removedcards map[int]struct{} + friends map[int]struct{} + removedfriends map[int]struct{} + best_friend *int + clearedbest_friend bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddCardIDs adds the cards edge to Card by ids. +func (m *UserMutation) AddCardIDs(ids ...int) { + if m.cards == nil { + m.cards = make(map[int]struct{}) + } + for i := range ids { + m.cards[ids[i]] = struct{}{} + } +} + +// RemoveCardIDs removes the cards edge to Card by ids. +func (m *UserMutation) RemoveCardIDs(ids ...int) { + if m.removedcards == nil { + m.removedcards = make(map[int]struct{}) + } + for i := range ids { + m.removedcards[ids[i]] = struct{}{} + } +} + +// RemovedCards returns the removed ids of cards. +func (m *UserMutation) RemovedCardsIDs() (ids []int) { + for id := range m.removedcards { + ids = append(ids, id) + } + return +} + +// CardsIDs returns the cards ids in the mutation. +func (m *UserMutation) CardsIDs() (ids []int) { + for id := range m.cards { + ids = append(ids, id) + } + return +} + +// ResetCards reset all changes of the cards edge. +func (m *UserMutation) ResetCards() { + m.cards = nil + m.removedcards = nil +} + +// AddFriendIDs adds the friends edge to User by ids. +func (m *UserMutation) AddFriendIDs(ids ...int) { + if m.friends == nil { + m.friends = make(map[int]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (m *UserMutation) RemoveFriendIDs(ids ...int) { + if m.removedfriends == nil { + m.removedfriends = make(map[int]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *UserMutation) RemovedFriendsIDs() (ids []int) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *UserMutation) FriendsIDs() (ids []int) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *UserMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// SetBestFriendID sets the best_friend edge to User by id. +func (m *UserMutation) SetBestFriendID(id int) { + m.best_friend = &id +} + +// ClearBestFriend clears the best_friend edge to User. +func (m *UserMutation) ClearBestFriend() { + m.clearedbest_friend = true +} + +// BestFriendCleared returns if the edge best_friend was cleared. +func (m *UserMutation) BestFriendCleared() bool { + return m.clearedbest_friend +} + +// BestFriendID returns the best_friend id in the mutation. +func (m *UserMutation) BestFriendID() (id int, exists bool) { + if m.best_friend != nil { + return *m.best_friend, true + } + return +} + +// BestFriendIDs returns the best_friend ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// BestFriendID instead. It exists only for internal usage by the builders. +func (m *UserMutation) BestFriendIDs() (ids []int) { + if id := m.best_friend; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetBestFriend reset all changes of the best_friend edge. +func (m *UserMutation) ResetBestFriend() { + m.best_friend = nil + m.clearedbest_friend = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 3) + if m.cards != nil { + edges = append(edges, user.EdgeCards) + } + if m.friends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.best_friend != nil { + edges = append(edges, user.EdgeBestFriend) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeCards: + ids := make([]ent.Value, 0, len(m.cards)) + for id := range m.cards { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + case user.EdgeBestFriend: + if id := m.best_friend; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 3) + if m.removedcards != nil { + edges = append(edges, user.EdgeCards) + } + if m.removedfriends != nil { + edges = append(edges, user.EdgeFriends) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeCards: + ids := make([]ent.Value, 0, len(m.removedcards)) + for id := range m.removedcards { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 3) + if m.clearedbest_friend { + edges = append(edges, user.EdgeBestFriend) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeBestFriend: + return m.clearedbest_friend + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeBestFriend: + m.ClearBestFriend() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeCards: + m.ResetCards() + return nil + case user.EdgeFriends: + m.ResetFriends() + return nil + case user.EdgeBestFriend: + m.ResetBestFriend() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/hooks/ent/predicate/predicate.go b/entc/integration/hooks/ent/predicate/predicate.go new file mode 100644 index 000000000..8aeaf6276 --- /dev/null +++ b/entc/integration/hooks/ent/predicate/predicate.go @@ -0,0 +1,17 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package predicate + +import ( + "github.com/facebookincubator/ent/dialect/sql" +) + +// Card is the predicate function for card builders. +type Card func(*sql.Selector) + +// User is the predicate function for user builders. +type User func(*sql.Selector) diff --git a/entc/integration/hooks/ent/privacy/privacy.go b/entc/integration/hooks/ent/privacy/privacy.go new file mode 100644 index 000000000..060c7df6b --- /dev/null +++ b/entc/integration/hooks/ent/privacy/privacy.go @@ -0,0 +1,195 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CardReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CardReadRuleFunc func(context.Context, *ent.Card) error + +// EvalRead calls f(ctx, v). +func (f CardReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Card); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Card", v) +} + +// The CardWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CardWriteRuleFunc func(context.Context, *ent.CardMutation) error + +// EvalWrite calls f(ctx, m). +func (f CardWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CardMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CardMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/hooks/ent/runtime.go b/entc/integration/hooks/ent/runtime.go new file mode 100644 index 000000000..3271d9493 --- /dev/null +++ b/entc/integration/hooks/ent/runtime.go @@ -0,0 +1,9 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/hooks/ent/runtime/runtime.go diff --git a/entc/integration/hooks/ent/runtime/runtime.go b/entc/integration/hooks/ent/runtime/runtime.go new file mode 100644 index 000000000..cb2c18981 --- /dev/null +++ b/entc/integration/hooks/ent/runtime/runtime.go @@ -0,0 +1,39 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +import ( + "time" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/schema" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + cardHooks := schema.Card{}.Hooks() + for i, h := range cardHooks { + card.Hooks[i] = h + } + cardFields := schema.Card{}.Fields() + // cardDescNumber is the schema descriptor for number field. + cardDescNumber := cardFields[0].Descriptor() + // card.DefaultNumber holds the default value on creation for the number field. + card.DefaultNumber = cardDescNumber.Default.(string) + // card.NumberValidator is a validator for the "number" field. It is called by the builders before save. + card.NumberValidator = cardDescNumber.Validators[0].(func(string) error) + // cardDescCreatedAt is the schema descriptor for created_at field. + cardDescCreatedAt := cardFields[2].Descriptor() + // card.DefaultCreatedAt holds the default value on creation for the created_at field. + card.DefaultCreatedAt = cardDescCreatedAt.Default.(func() time.Time) +} + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/hooks/ent/schema/card.go b/entc/integration/hooks/ent/schema/card.go new file mode 100644 index 000000000..e46b40fe4 --- /dev/null +++ b/entc/integration/hooks/ent/schema/card.go @@ -0,0 +1,76 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package schema + +import ( + "context" + "fmt" + "time" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + + "github.com/facebookincubator/ent" + gen "github.com/facebookincubator/ent/entc/integration/hooks/ent" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/hook" + + "github.com/facebookincubator/ent/schema/edge" + "github.com/facebookincubator/ent/schema/field" +) + +// Card holds the schema definition for the CreditCard entity. +type Card struct { + ent.Schema +} + +func (Card) Hooks() []ent.Hook { + return []ent.Hook{ + hook.On( + func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + num, ok := m.Field(card.FieldNumber) + if !ok { + return nil, fmt.Errorf("missing card number value") + } + // Validator in hooks. + if len(num.(string)) < 4 { + return nil, fmt.Errorf("card number is too short") + } + return next.Mutate(ctx, m) + }) + }, + ent.OpCreate|ent.OpUpdate|ent.OpUpdateOne, + ), + func(next ent.Mutator) ent.Mutator { + return hook.CardFunc(func(ctx context.Context, m *gen.CardMutation) (ent.Value, error) { + if _, ok := m.Name(); !ok { + m.SetName("unknown") + } + return next.Mutate(ctx, m) + }) + }, + } +} + +func (Card) Fields() []ent.Field { + return []ent.Field{ + field.String("number"). + Immutable(). + Default("unknown"). + NotEmpty(), + field.String("name"). + Optional(). + Comment("Exact name written on card"), + field.Time("created_at"). + Default(time.Now), + } +} + +func (Card) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("owner", User.Type). + Ref("cards"). + Unique(), + } +} diff --git a/entc/integration/hooks/ent/schema/user.go b/entc/integration/hooks/ent/schema/user.go new file mode 100644 index 000000000..7f41bdeb8 --- /dev/null +++ b/entc/integration/hooks/ent/schema/user.go @@ -0,0 +1,29 @@ +package schema + +import ( + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/schema/edge" + "github.com/facebookincubator/ent/schema/field" +) + +// User holds the schema definition for the User entity. +type User struct { + ent.Schema +} + +// Fields of the User. +func (User) Fields() []ent.Field { + return []ent.Field{ + field.String("name"), + } +} + +// Edges of the User. +func (User) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("cards", Card.Type), + edge.To("friends", User.Type), + edge.To("best_friend", User.Type). + Unique(), + } +} diff --git a/entc/integration/hooks/ent/tx.go b/entc/integration/hooks/ent/tx.go new file mode 100644 index 000000000..f671a76d1 --- /dev/null +++ b/entc/integration/hooks/ent/tx.go @@ -0,0 +1,101 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + + "github.com/facebookincubator/ent/dialect" +) + +// Tx is a transactional client that is created by calling Client.Tx(). +type Tx struct { + config + // Card is the client for interacting with the Card builders. + Card *CardClient + // User is the client for interacting with the User builders. + User *UserClient +} + +// Commit commits the transaction. +func (tx *Tx) Commit() error { + return tx.config.driver.(*txDriver).tx.Commit() +} + +// Rollback rollbacks the transaction. +func (tx *Tx) Rollback() error { + return tx.config.driver.(*txDriver).tx.Rollback() +} + +// Client returns a Client that binds to current transaction. +func (tx *Tx) Client() *Client { + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Card = NewCardClient(tx.config) + tx.User = NewUserClient(tx.config) +} + +// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. +// The idea is to support transactions without adding any extra code to the builders. +// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. +// Commit and Rollback are nop for the internal builders and the user must call one +// of them in order to commit or rollback the transaction. +// +// If a closed transaction is embedded in one of the generated entities, and the entity +// applies a query, for example: Card.QueryXXX(), the query will be executed +// through the driver which created this transaction. +// +// Note that txDriver is not goroutine safe. +type txDriver struct { + // the driver we started the transaction from. + drv dialect.Driver + // tx is the underlying transaction. + tx dialect.Tx +} + +// newTx creates a new transactional driver. +func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { + tx, err := drv.Tx(ctx) + if err != nil { + return nil, err + } + return &txDriver{tx: tx, drv: drv}, nil +} + +// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls +// from the internal builders. Should be called only by the internal builders. +func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } + +// Dialect returns the dialect of the driver we started the transaction from. +func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } + +// Close is a nop close. +func (*txDriver) Close() error { return nil } + +// Commit is a nop commit for the internal builders. +// User must call `Tx.Commit` in order to commit the transaction. +func (*txDriver) Commit() error { return nil } + +// Rollback is a nop rollback for the internal builders. +// User must call `Tx.Rollback` in order to rollback the transaction. +func (*txDriver) Rollback() error { return nil } + +// Exec calls tx.Exec. +func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error { + return tx.tx.Exec(ctx, query, args, v) +} + +// Query calls tx.Query. +func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error { + return tx.tx.Query(ctx, query, args, v) +} + +var _ dialect.Driver = (*txDriver)(nil) diff --git a/entc/integration/hooks/ent/user.go b/entc/integration/hooks/ent/user.go new file mode 100644 index 000000000..af23b96d0 --- /dev/null +++ b/entc/integration/hooks/ent/user.go @@ -0,0 +1,170 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" +) + +// User is the model entity for the User schema. +type User struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the UserQuery when eager-loading is set. + Edges UserEdges `json:"edges"` + user_best_friend *int +} + +// UserEdges holds the relations/edges for other nodes in the graph. +type UserEdges struct { + // Cards holds the value of the cards edge. + Cards []*Card + // Friends holds the value of the friends edge. + Friends []*User + // BestFriend holds the value of the best_friend edge. + BestFriend *User + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [3]bool +} + +// CardsOrErr returns the Cards value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) CardsOrErr() ([]*Card, error) { + if e.loadedTypes[0] { + return e.Cards, nil + } + return nil, &NotLoadedError{edge: "cards"} +} + +// FriendsOrErr returns the Friends value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) FriendsOrErr() ([]*User, error) { + if e.loadedTypes[1] { + return e.Friends, nil + } + return nil, &NotLoadedError{edge: "friends"} +} + +// BestFriendOrErr returns the BestFriend value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e UserEdges) BestFriendOrErr() (*User, error) { + if e.loadedTypes[2] { + if e.BestFriend == nil { + // The edge best_friend was loaded in eager-loading, + // but was not found. + return nil, &NotFoundError{label: user.Label} + } + return e.BestFriend, nil + } + return nil, &NotLoadedError{edge: "best_friend"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*User) scanValues() []interface{} { + return []interface{}{ + &sql.NullInt64{}, // id + &sql.NullString{}, // name + } +} + +// fkValues returns the types for scanning foreign-keys values from sql.Rows. +func (*User) fkValues() []interface{} { + return []interface{}{ + &sql.NullInt64{}, // user_best_friend + } +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the User fields. +func (u *User) assignValues(values ...interface{}) error { + if m, n := len(values), len(user.Columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + value, ok := values[0].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + u.ID = int(value.Int64) + values = values[1:] + if value, ok := values[0].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[0]) + } else if value.Valid { + u.Name = value.String + } + values = values[1:] + if len(values) == len(user.ForeignKeys) { + if value, ok := values[0].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for edge-field user_best_friend", value) + } else if value.Valid { + u.user_best_friend = new(int) + *u.user_best_friend = int(value.Int64) + } + } + return nil +} + +// QueryCards queries the cards edge of the User. +func (u *User) QueryCards() *CardQuery { + return (&UserClient{config: u.config}).QueryCards(u) +} + +// QueryFriends queries the friends edge of the User. +func (u *User) QueryFriends() *UserQuery { + return (&UserClient{config: u.config}).QueryFriends(u) +} + +// QueryBestFriend queries the best_friend edge of the User. +func (u *User) QueryBestFriend() *UserQuery { + return (&UserClient{config: u.config}).QueryBestFriend(u) +} + +// Update returns a builder for updating this User. +// Note that, you need to call User.Unwrap() before calling this method, if this User +// was returned from a transaction, and the transaction was committed or rolled back. +func (u *User) Update() *UserUpdateOne { + return (&UserClient{config: u.config}).UpdateOne(u) +} + +// Unwrap unwraps the entity that was returned from a transaction after it was closed, +// so that all next queries will be executed through the driver which created the transaction. +func (u *User) Unwrap() *User { + tx, ok := u.config.driver.(*txDriver) + if !ok { + panic("ent: User is not a transactional entity") + } + u.config.driver = tx.drv + return u +} + +// String implements the fmt.Stringer. +func (u *User) String() string { + var builder strings.Builder + builder.WriteString("User(") + builder.WriteString(fmt.Sprintf("id=%v", u.ID)) + builder.WriteString(", name=") + builder.WriteString(u.Name) + builder.WriteByte(')') + return builder.String() +} + +// Users is a parsable slice of User. +type Users []*User + +func (u Users) config(cfg config) { + for _i := range u { + u[_i].config = cfg + } +} diff --git a/entc/integration/hooks/ent/user/user.go b/entc/integration/hooks/ent/user/user.go new file mode 100644 index 000000000..4ba58ddcf --- /dev/null +++ b/entc/integration/hooks/ent/user/user.go @@ -0,0 +1,55 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package user + +const ( + // Label holds the string label denoting the user type in the database. + Label = "user" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" + + // EdgeCards holds the string denoting the cards edge name in mutations. + EdgeCards = "cards" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // EdgeBestFriend holds the string denoting the best_friend edge name in mutations. + EdgeBestFriend = "best_friend" + + // Table holds the table name of the user in the database. + Table = "users" + // CardsTable is the table the holds the cards relation/edge. + CardsTable = "cards" + // CardsInverseTable is the table name for the Card entity. + // It exists in this package in order to avoid circular dependency with the "card" package. + CardsInverseTable = "cards" + // CardsColumn is the table column denoting the cards relation/edge. + CardsColumn = "user_cards" + // FriendsTable is the table the holds the friends relation/edge. The primary key declared below. + FriendsTable = "user_friends" + // BestFriendTable is the table the holds the best_friend relation/edge. + BestFriendTable = "users" + // BestFriendColumn is the table column denoting the best_friend relation/edge. + BestFriendColumn = "user_best_friend" +) + +// Columns holds all SQL columns for user fields. +var Columns = []string{ + FieldID, + FieldName, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the User type. +var ForeignKeys = []string{ + "user_best_friend", +} + +var ( + // FriendsPrimaryKey and FriendsColumn2 are the table columns denoting the + // primary key for the friends relation (M2M). + FriendsPrimaryKey = []string{"user_id", "friend_id"} +) diff --git a/entc/integration/hooks/ent/user/where.go b/entc/integration/hooks/ent/user/where.go new file mode 100644 index 000000000..64d1c491e --- /dev/null +++ b/entc/integration/hooks/ent/user/where.go @@ -0,0 +1,330 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package user + +import ( + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" +) + +// ID filters vertices based on their identifier. +func ID(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldID), id)) + }) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.User { + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.In(s.C(FieldID), v...)) + }) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.User { + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.NotIn(s.C(FieldID), v...)) + }) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldID), id)) + }) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldID), id)) + }) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldID), id)) + }) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldID), id)) + }) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldName), v)) + }) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldName), v)) + }) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldName), v)) + }) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.User { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldName), v...)) + }) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.User { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldName), v...)) + }) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldName), v)) + }) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldName), v)) + }) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldName), v)) + }) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldName), v)) + }) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.Contains(s.C(FieldName), v)) + }) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.HasPrefix(s.C(FieldName), v)) + }) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.HasSuffix(s.C(FieldName), v)) + }) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EqualFold(s.C(FieldName), v)) + }) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.ContainsFold(s.C(FieldName), v)) + }) +} + +// HasCards applies the HasEdge predicate on the "cards" edge. +func HasCards() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(CardsTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, CardsTable, CardsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasCardsWith applies the HasEdge predicate on the "cards" edge with a given conditions (other predicates). +func HasCardsWith(preds ...predicate.Card) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(CardsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, CardsTable, CardsColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasFriends applies the HasEdge predicate on the "friends" edge. +func HasFriends() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(FriendsTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, FriendsTable, FriendsPrimaryKey...), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasFriendsWith applies the HasEdge predicate on the "friends" edge with a given conditions (other predicates). +func HasFriendsWith(preds ...predicate.User) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, FriendsTable, FriendsPrimaryKey...), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasBestFriend applies the HasEdge predicate on the "best_friend" edge. +func HasBestFriend() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(BestFriendTable, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, BestFriendTable, BestFriendColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasBestFriendWith applies the HasEdge predicate on the "best_friend" edge with a given conditions (other predicates). +func HasBestFriendWith(preds ...predicate.User) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, BestFriendTable, BestFriendColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups list of predicates with the AND operator between them. +func And(predicates ...predicate.User) predicate.User { + return predicate.User(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for _, p := range predicates { + p(s1) + } + s.Where(s1.P()) + }) +} + +// Or groups list of predicates with the OR operator between them. +func Or(predicates ...predicate.User) predicate.User { + return predicate.User(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for i, p := range predicates { + if i > 0 { + s1.Or() + } + p(s1) + } + s.Where(s1.P()) + }) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.User) predicate.User { + return predicate.User(func(s *sql.Selector) { + p(s.Not()) + }) +} diff --git a/entc/integration/hooks/ent/user_create.go b/entc/integration/hooks/ent/user_create.go new file mode 100644 index 000000000..65b1263a8 --- /dev/null +++ b/entc/integration/hooks/ent/user_create.go @@ -0,0 +1,207 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// UserCreate is the builder for creating a User entity. +type UserCreate struct { + config + mutation *UserMutation + hooks []Hook +} + +// SetName sets the name field. +func (uc *UserCreate) SetName(s string) *UserCreate { + uc.mutation.SetName(s) + return uc +} + +// AddCardIDs adds the cards edge to Card by ids. +func (uc *UserCreate) AddCardIDs(ids ...int) *UserCreate { + uc.mutation.AddCardIDs(ids...) + return uc +} + +// AddCards adds the cards edges to Card. +func (uc *UserCreate) AddCards(c ...*Card) *UserCreate { + ids := make([]int, len(c)) + for i := range c { + ids[i] = c[i].ID + } + return uc.AddCardIDs(ids...) +} + +// AddFriendIDs adds the friends edge to User by ids. +func (uc *UserCreate) AddFriendIDs(ids ...int) *UserCreate { + uc.mutation.AddFriendIDs(ids...) + return uc +} + +// AddFriends adds the friends edges to User. +func (uc *UserCreate) AddFriends(u ...*User) *UserCreate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return uc.AddFriendIDs(ids...) +} + +// SetBestFriendID sets the best_friend edge to User by id. +func (uc *UserCreate) SetBestFriendID(id int) *UserCreate { + uc.mutation.SetBestFriendID(id) + return uc +} + +// SetNillableBestFriendID sets the best_friend edge to User by id if the given value is not nil. +func (uc *UserCreate) SetNillableBestFriendID(id *int) *UserCreate { + if id != nil { + uc = uc.SetBestFriendID(*id) + } + return uc +} + +// SetBestFriend sets the best_friend edge to User. +func (uc *UserCreate) SetBestFriend(u *User) *UserCreate { + return uc.SetBestFriendID(u.ID) +} + +// Save creates the User in the database. +func (uc *UserCreate) Save(ctx context.Context) (*User, error) { + if _, ok := uc.mutation.Name(); !ok { + return nil, errors.New("ent: missing required field \"name\"") + } + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX calls Save and panics if Save returns an error. +func (uc *UserCreate) SaveX(ctx context.Context) *User { + v, err := uc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { + var ( + u = &User{config: uc.config} + _spec = &sqlgraph.CreateSpec{ + Table: user.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + } + ) + if value, ok := uc.mutation.Name(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: user.FieldName, + }) + u.Name = value + } + if nodes := uc.mutation.CardsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CardsTable, + Columns: []string{user.CardsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := uc.mutation.FriendsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.FriendsTable, + Columns: user.FriendsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := uc.mutation.BestFriendIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: user.BestFriendTable, + Columns: []string{user.BestFriendColumn}, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if err := sqlgraph.CreateNode(ctx, uc.driver, _spec); err != nil { + if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return nil, err + } + id := _spec.ID.Value.(int64) + u.ID = int(id) + return u, nil +} diff --git a/entc/integration/hooks/ent/user_delete.go b/entc/integration/hooks/ent/user_delete.go new file mode 100644 index 000000000..8bfa37838 --- /dev/null +++ b/entc/integration/hooks/ent/user_delete.go @@ -0,0 +1,112 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// UserDelete is the builder for deleting a User entity. +type UserDelete struct { + config + hooks []Hook + mutation *UserMutation + predicates []predicate.User +} + +// Where adds a new predicate to the delete builder. +func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { + ud.predicates = append(ud.predicates, ps...) + return ud +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (ud *UserDelete) Exec(ctx context.Context) (int, error) { + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// ExecX is like Exec, but panics if an error occurs. +func (ud *UserDelete) ExecX(ctx context.Context) int { + n, err := ud.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (ud *UserDelete) sqlExec(ctx context.Context) (int, error) { + _spec := &sqlgraph.DeleteSpec{ + Node: &sqlgraph.NodeSpec{ + Table: user.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + if ps := ud.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return sqlgraph.DeleteNodes(ctx, ud.driver, _spec) +} + +// UserDeleteOne is the builder for deleting a single User entity. +type UserDeleteOne struct { + ud *UserDelete +} + +// Exec executes the deletion query. +func (udo *UserDeleteOne) Exec(ctx context.Context) error { + n, err := udo.ud.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{user.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (udo *UserDeleteOne) ExecX(ctx context.Context) { + udo.ud.ExecX(ctx) +} diff --git a/entc/integration/hooks/ent/user_query.go b/entc/integration/hooks/ent/user_query.go new file mode 100644 index 000000000..db1fae4f9 --- /dev/null +++ b/entc/integration/hooks/ent/user_query.go @@ -0,0 +1,827 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "errors" + "fmt" + "math" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// UserQuery is the builder for querying User entities. +type UserQuery struct { + config + limit *int + offset *int + order []Order + unique []string + predicates []predicate.User + // eager-loading edges. + withCards *CardQuery + withFriends *UserQuery + withBestFriend *UserQuery + withFKs bool + // intermediate query. + sql *sql.Selector +} + +// Where adds a new predicate for the builder. +func (uq *UserQuery) Where(ps ...predicate.User) *UserQuery { + uq.predicates = append(uq.predicates, ps...) + return uq +} + +// Limit adds a limit step to the query. +func (uq *UserQuery) Limit(limit int) *UserQuery { + uq.limit = &limit + return uq +} + +// Offset adds an offset step to the query. +func (uq *UserQuery) Offset(offset int) *UserQuery { + uq.offset = &offset + return uq +} + +// Order adds an order step to the query. +func (uq *UserQuery) Order(o ...Order) *UserQuery { + uq.order = append(uq.order, o...) + return uq +} + +// QueryCards chains the current query on the cards edge. +func (uq *UserQuery) QueryCards() *CardQuery { + query := &CardQuery{config: uq.config} + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, uq.sqlQuery()), + sqlgraph.To(card.Table, card.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.CardsTable, user.CardsColumn), + ) + query.sql = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return query +} + +// QueryFriends chains the current query on the friends edge. +func (uq *UserQuery) QueryFriends() *UserQuery { + query := &UserQuery{config: uq.config} + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, uq.sqlQuery()), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, user.FriendsTable, user.FriendsPrimaryKey...), + ) + query.sql = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return query +} + +// QueryBestFriend chains the current query on the best_friend edge. +func (uq *UserQuery) QueryBestFriend() *UserQuery { + query := &UserQuery{config: uq.config} + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, uq.sqlQuery()), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, user.BestFriendTable, user.BestFriendColumn), + ) + query.sql = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return query +} + +// First returns the first User entity in the query. Returns *NotFoundError when no user was found. +func (uq *UserQuery) First(ctx context.Context) (*User, error) { + us, err := uq.Limit(1).All(ctx) + if err != nil { + return nil, err + } + if len(us) == 0 { + return nil, &NotFoundError{user.Label} + } + return us[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (uq *UserQuery) FirstX(ctx context.Context) *User { + u, err := uq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return u +} + +// FirstID returns the first User id in the query. Returns *NotFoundError when no id was found. +func (uq *UserQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = uq.Limit(1).IDs(ctx); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{user.Label} + return + } + return ids[0], nil +} + +// FirstXID is like FirstID, but panics if an error occurs. +func (uq *UserQuery) FirstXID(ctx context.Context) int { + id, err := uq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns the only User entity in the query, returns an error if not exactly one entity was returned. +func (uq *UserQuery) Only(ctx context.Context) (*User, error) { + us, err := uq.Limit(2).All(ctx) + if err != nil { + return nil, err + } + switch len(us) { + case 1: + return us[0], nil + case 0: + return nil, &NotFoundError{user.Label} + default: + return nil, &NotSingularError{user.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (uq *UserQuery) OnlyX(ctx context.Context) *User { + u, err := uq.Only(ctx) + if err != nil { + panic(err) + } + return u +} + +// OnlyID returns the only User id in the query, returns an error if not exactly one id was returned. +func (uq *UserQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = uq.Limit(2).IDs(ctx); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{user.Label} + default: + err = &NotSingularError{user.Label} + } + return +} + +// OnlyXID is like OnlyID, but panics if an error occurs. +func (uq *UserQuery) OnlyXID(ctx context.Context) int { + id, err := uq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Users. +func (uq *UserQuery) All(ctx context.Context) ([]*User, error) { + return uq.sqlAll(ctx) +} + +// AllX is like All, but panics if an error occurs. +func (uq *UserQuery) AllX(ctx context.Context) []*User { + us, err := uq.All(ctx) + if err != nil { + panic(err) + } + return us +} + +// IDs executes the query and returns a list of User ids. +func (uq *UserQuery) IDs(ctx context.Context) ([]int, error) { + var ids []int + if err := uq.Select(user.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (uq *UserQuery) IDsX(ctx context.Context) []int { + ids, err := uq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (uq *UserQuery) Count(ctx context.Context) (int, error) { + return uq.sqlCount(ctx) +} + +// CountX is like Count, but panics if an error occurs. +func (uq *UserQuery) CountX(ctx context.Context) int { + count, err := uq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (uq *UserQuery) Exist(ctx context.Context) (bool, error) { + return uq.sqlExist(ctx) +} + +// ExistX is like Exist, but panics if an error occurs. +func (uq *UserQuery) ExistX(ctx context.Context) bool { + exist, err := uq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the query builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (uq *UserQuery) Clone() *UserQuery { + return &UserQuery{ + config: uq.config, + limit: uq.limit, + offset: uq.offset, + order: append([]Order{}, uq.order...), + unique: append([]string{}, uq.unique...), + predicates: append([]predicate.User{}, uq.predicates...), + // clone intermediate query. + sql: uq.sql.Clone(), + } +} + +// WithCards tells the query-builder to eager-loads the nodes that are connected to +// the "cards" edge. The optional arguments used to configure the query builder of the edge. +func (uq *UserQuery) WithCards(opts ...func(*CardQuery)) *UserQuery { + query := &CardQuery{config: uq.config} + for _, opt := range opts { + opt(query) + } + uq.withCards = query + return uq +} + +// WithFriends tells the query-builder to eager-loads the nodes that are connected to +// the "friends" edge. The optional arguments used to configure the query builder of the edge. +func (uq *UserQuery) WithFriends(opts ...func(*UserQuery)) *UserQuery { + query := &UserQuery{config: uq.config} + for _, opt := range opts { + opt(query) + } + uq.withFriends = query + return uq +} + +// WithBestFriend tells the query-builder to eager-loads the nodes that are connected to +// the "best_friend" edge. The optional arguments used to configure the query builder of the edge. +func (uq *UserQuery) WithBestFriend(opts ...func(*UserQuery)) *UserQuery { + query := &UserQuery{config: uq.config} + for _, opt := range opts { + opt(query) + } + uq.withBestFriend = query + return uq +} + +// GroupBy used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.User.Query(). +// GroupBy(user.FieldName). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +// +func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy { + group := &UserGroupBy{config: uq.config} + group.fields = append([]string{field}, fields...) + group.sql = uq.sqlQuery() + return group +} + +// Select one or more fields from the given query. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// } +// +// client.User.Query(). +// Select(user.FieldName). +// Scan(ctx, &v) +// +func (uq *UserQuery) Select(field string, fields ...string) *UserSelect { + selector := &UserSelect{config: uq.config} + selector.fields = append([]string{field}, fields...) + selector.sql = uq.sqlQuery() + return selector +} + +func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) { + var ( + nodes = []*User{} + withFKs = uq.withFKs + _spec = uq.querySpec() + loadedTypes = [3]bool{ + uq.withCards != nil, + uq.withFriends != nil, + uq.withBestFriend != nil, + } + ) + if uq.withBestFriend != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, user.ForeignKeys...) + } + _spec.ScanValues = func() []interface{} { + node := &User{config: uq.config} + nodes = append(nodes, node) + values := node.scanValues() + if withFKs { + values = append(values, node.fkValues()...) + } + return values + } + _spec.Assign = func(values ...interface{}) error { + if len(nodes) == 0 { + return fmt.Errorf("ent: Assign called without calling ScanValues") + } + node := nodes[len(nodes)-1] + node.Edges.loadedTypes = loadedTypes + return node.assignValues(values...) + } + if err := sqlgraph.QueryNodes(ctx, uq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + + if query := uq.withCards; query != nil { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + } + query.withFKs = true + query.Where(predicate.Card(func(s *sql.Selector) { + s.Where(sql.InValues(user.CardsColumn, fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + fk := n.user_cards + if fk == nil { + return nil, fmt.Errorf(`foreign-key "user_cards" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "user_cards" returned %v for node %v`, *fk, n.ID) + } + node.Edges.Cards = append(node.Edges.Cards, n) + } + } + + if query := uq.withFriends; query != nil { + fks := make([]driver.Value, 0, len(nodes)) + ids := make(map[int]*User, len(nodes)) + for _, node := range nodes { + ids[node.ID] = node + fks = append(fks, node.ID) + } + var ( + edgeids []int + edges = make(map[int][]*User) + ) + _spec := &sqlgraph.EdgeQuerySpec{ + Edge: &sqlgraph.EdgeSpec{ + Inverse: false, + Table: user.FriendsTable, + Columns: user.FriendsPrimaryKey, + }, + Predicate: func(s *sql.Selector) { + s.Where(sql.InValues(user.FriendsPrimaryKey[0], fks...)) + }, + + ScanValues: func() [2]interface{} { + return [2]interface{}{&sql.NullInt64{}, &sql.NullInt64{}} + }, + Assign: func(out, in interface{}) error { + eout, ok := out.(*sql.NullInt64) + if !ok || eout == nil { + return fmt.Errorf("unexpected id value for edge-out") + } + ein, ok := in.(*sql.NullInt64) + if !ok || ein == nil { + return fmt.Errorf("unexpected id value for edge-in") + } + outValue := int(eout.Int64) + inValue := int(ein.Int64) + node, ok := ids[outValue] + if !ok { + return fmt.Errorf("unexpected node id in edges: %v", outValue) + } + edgeids = append(edgeids, inValue) + edges[inValue] = append(edges[inValue], node) + return nil + }, + } + if err := sqlgraph.QueryEdges(ctx, uq.driver, _spec); err != nil { + return nil, fmt.Errorf(`query edges "friends": %v`, err) + } + query.Where(user.IDIn(edgeids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := edges[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected "friends" node returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.Friends = append(nodes[i].Edges.Friends, n) + } + } + } + + if query := uq.withBestFriend; query != nil { + ids := make([]int, 0, len(nodes)) + nodeids := make(map[int][]*User) + for i := range nodes { + if fk := nodes[i].user_best_friend; fk != nil { + ids = append(ids, *fk) + nodeids[*fk] = append(nodeids[*fk], nodes[i]) + } + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "user_best_friend" returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.BestFriend = n + } + } + } + + return nodes, nil +} + +func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) { + _spec := uq.querySpec() + return sqlgraph.CountNodes(ctx, uq.driver, _spec) +} + +func (uq *UserQuery) sqlExist(ctx context.Context) (bool, error) { + n, err := uq.sqlCount(ctx) + if err != nil { + return false, fmt.Errorf("ent: check existence: %v", err) + } + return n > 0, nil +} + +func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec { + _spec := &sqlgraph.QuerySpec{ + Node: &sqlgraph.NodeSpec{ + Table: user.Table, + Columns: user.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + From: uq.sql, + Unique: true, + } + if ps := uq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := uq.limit; limit != nil { + _spec.Limit = *limit + } + if offset := uq.offset; offset != nil { + _spec.Offset = *offset + } + if ps := uq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (uq *UserQuery) sqlQuery() *sql.Selector { + builder := sql.Dialect(uq.driver.Dialect()) + t1 := builder.Table(user.Table) + selector := builder.Select(t1.Columns(user.Columns...)...).From(t1) + if uq.sql != nil { + selector = uq.sql + selector.Select(selector.Columns(user.Columns...)...) + } + for _, p := range uq.predicates { + p(selector) + } + for _, p := range uq.order { + p(selector) + } + if offset := uq.offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := uq.limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// UserGroupBy is the builder for group-by User entities. +type UserGroupBy struct { + config + fields []string + fns []Aggregate + // intermediate query. + sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (ugb *UserGroupBy) Aggregate(fns ...Aggregate) *UserGroupBy { + ugb.fns = append(ugb.fns, fns...) + return ugb +} + +// Scan applies the group-by query and scan the result into the given value. +func (ugb *UserGroupBy) Scan(ctx context.Context, v interface{}) error { + return ugb.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (ugb *UserGroupBy) ScanX(ctx context.Context, v interface{}) { + if err := ugb.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Strings(ctx context.Context) ([]string, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Strings is not achievable when grouping more than 1 field") + } + var v []string + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (ugb *UserGroupBy) StringsX(ctx context.Context) []string { + v, err := ugb.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Ints(ctx context.Context) ([]int, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Ints is not achievable when grouping more than 1 field") + } + var v []int + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (ugb *UserGroupBy) IntsX(ctx context.Context) []int { + v, err := ugb.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Float64s(ctx context.Context) ([]float64, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Float64s is not achievable when grouping more than 1 field") + } + var v []float64 + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (ugb *UserGroupBy) Float64sX(ctx context.Context) []float64 { + v, err := ugb.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Bools(ctx context.Context) ([]bool, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Bools is not achievable when grouping more than 1 field") + } + var v []bool + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (ugb *UserGroupBy) BoolsX(ctx context.Context) []bool { + v, err := ugb.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (ugb *UserGroupBy) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := ugb.sqlQuery().Query() + if err := ugb.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (ugb *UserGroupBy) sqlQuery() *sql.Selector { + selector := ugb.sql + columns := make([]string, 0, len(ugb.fields)+len(ugb.fns)) + columns = append(columns, ugb.fields...) + for _, fn := range ugb.fns { + columns = append(columns, fn(selector)) + } + return selector.Select(columns...).GroupBy(ugb.fields...) +} + +// UserSelect is the builder for select fields of User entities. +type UserSelect struct { + config + fields []string + // intermediate queries. + sql *sql.Selector +} + +// Scan applies the selector query and scan the result into the given value. +func (us *UserSelect) Scan(ctx context.Context, v interface{}) error { + return us.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (us *UserSelect) ScanX(ctx context.Context, v interface{}) { + if err := us.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from selector. It is only allowed when selecting one field. +func (us *UserSelect) Strings(ctx context.Context) ([]string, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (us *UserSelect) StringsX(ctx context.Context) []string { + v, err := us.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from selector. It is only allowed when selecting one field. +func (us *UserSelect) Ints(ctx context.Context) ([]int, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (us *UserSelect) IntsX(ctx context.Context) []int { + v, err := us.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from selector. It is only allowed when selecting one field. +func (us *UserSelect) Float64s(ctx context.Context) ([]float64, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (us *UserSelect) Float64sX(ctx context.Context) []float64 { + v, err := us.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from selector. It is only allowed when selecting one field. +func (us *UserSelect) Bools(ctx context.Context) ([]bool, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (us *UserSelect) BoolsX(ctx context.Context) []bool { + v, err := us.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (us *UserSelect) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := us.sqlQuery().Query() + if err := us.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (us *UserSelect) sqlQuery() sql.Querier { + selector := us.sql + selector.Select(selector.Columns(us.fields...)...) + return selector +} diff --git a/entc/integration/hooks/ent/user_update.go b/entc/integration/hooks/ent/user_update.go new file mode 100644 index 000000000..9e83da461 --- /dev/null +++ b/entc/integration/hooks/ent/user_update.go @@ -0,0 +1,619 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + "github.com/facebookincubator/ent/schema/field" +) + +// UserUpdate is the builder for updating User entities. +type UserUpdate struct { + config + hooks []Hook + mutation *UserMutation + predicates []predicate.User +} + +// Where adds a new predicate for the builder. +func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { + uu.predicates = append(uu.predicates, ps...) + return uu +} + +// SetName sets the name field. +func (uu *UserUpdate) SetName(s string) *UserUpdate { + uu.mutation.SetName(s) + return uu +} + +// AddCardIDs adds the cards edge to Card by ids. +func (uu *UserUpdate) AddCardIDs(ids ...int) *UserUpdate { + uu.mutation.AddCardIDs(ids...) + return uu +} + +// AddCards adds the cards edges to Card. +func (uu *UserUpdate) AddCards(c ...*Card) *UserUpdate { + ids := make([]int, len(c)) + for i := range c { + ids[i] = c[i].ID + } + return uu.AddCardIDs(ids...) +} + +// AddFriendIDs adds the friends edge to User by ids. +func (uu *UserUpdate) AddFriendIDs(ids ...int) *UserUpdate { + uu.mutation.AddFriendIDs(ids...) + return uu +} + +// AddFriends adds the friends edges to User. +func (uu *UserUpdate) AddFriends(u ...*User) *UserUpdate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return uu.AddFriendIDs(ids...) +} + +// SetBestFriendID sets the best_friend edge to User by id. +func (uu *UserUpdate) SetBestFriendID(id int) *UserUpdate { + uu.mutation.SetBestFriendID(id) + return uu +} + +// SetNillableBestFriendID sets the best_friend edge to User by id if the given value is not nil. +func (uu *UserUpdate) SetNillableBestFriendID(id *int) *UserUpdate { + if id != nil { + uu = uu.SetBestFriendID(*id) + } + return uu +} + +// SetBestFriend sets the best_friend edge to User. +func (uu *UserUpdate) SetBestFriend(u *User) *UserUpdate { + return uu.SetBestFriendID(u.ID) +} + +// RemoveCardIDs removes the cards edge to Card by ids. +func (uu *UserUpdate) RemoveCardIDs(ids ...int) *UserUpdate { + uu.mutation.RemoveCardIDs(ids...) + return uu +} + +// RemoveCards removes cards edges to Card. +func (uu *UserUpdate) RemoveCards(c ...*Card) *UserUpdate { + ids := make([]int, len(c)) + for i := range c { + ids[i] = c[i].ID + } + return uu.RemoveCardIDs(ids...) +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (uu *UserUpdate) RemoveFriendIDs(ids ...int) *UserUpdate { + uu.mutation.RemoveFriendIDs(ids...) + return uu +} + +// RemoveFriends removes friends edges to User. +func (uu *UserUpdate) RemoveFriends(u ...*User) *UserUpdate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return uu.RemoveFriendIDs(ids...) +} + +// ClearBestFriend clears the best_friend edge to User. +func (uu *UserUpdate) ClearBestFriend() *UserUpdate { + uu.mutation.ClearBestFriend() + return uu +} + +// Save executes the query and returns the number of rows/vertices matched by this operation. +func (uu *UserUpdate) Save(ctx context.Context) (int, error) { + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// SaveX is like Save, but panics if an error occurs. +func (uu *UserUpdate) SaveX(ctx context.Context) int { + affected, err := uu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (uu *UserUpdate) Exec(ctx context.Context) error { + _, err := uu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uu *UserUpdate) ExecX(ctx context.Context) { + if err := uu.Exec(ctx); err != nil { + panic(err) + } +} + +func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: user.Table, + Columns: user.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + if ps := uu.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := uu.mutation.Name(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: user.FieldName, + }) + } + if nodes := uu.mutation.RemovedCardsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CardsTable, + Columns: []string{user.CardsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.CardsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CardsTable, + Columns: []string{user.CardsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if nodes := uu.mutation.RemovedFriendsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.FriendsTable, + Columns: user.FriendsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.FriendsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.FriendsTable, + Columns: user.FriendsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if uu.mutation.BestFriendCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: user.BestFriendTable, + Columns: []string{user.BestFriendColumn}, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.BestFriendIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: user.BestFriendTable, + Columns: []string{user.BestFriendColumn}, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{user.Label} + } else if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return 0, err + } + return n, nil +} + +// UserUpdateOne is the builder for updating a single User entity. +type UserUpdateOne struct { + config + hooks []Hook + mutation *UserMutation +} + +// SetName sets the name field. +func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { + uuo.mutation.SetName(s) + return uuo +} + +// AddCardIDs adds the cards edge to Card by ids. +func (uuo *UserUpdateOne) AddCardIDs(ids ...int) *UserUpdateOne { + uuo.mutation.AddCardIDs(ids...) + return uuo +} + +// AddCards adds the cards edges to Card. +func (uuo *UserUpdateOne) AddCards(c ...*Card) *UserUpdateOne { + ids := make([]int, len(c)) + for i := range c { + ids[i] = c[i].ID + } + return uuo.AddCardIDs(ids...) +} + +// AddFriendIDs adds the friends edge to User by ids. +func (uuo *UserUpdateOne) AddFriendIDs(ids ...int) *UserUpdateOne { + uuo.mutation.AddFriendIDs(ids...) + return uuo +} + +// AddFriends adds the friends edges to User. +func (uuo *UserUpdateOne) AddFriends(u ...*User) *UserUpdateOne { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return uuo.AddFriendIDs(ids...) +} + +// SetBestFriendID sets the best_friend edge to User by id. +func (uuo *UserUpdateOne) SetBestFriendID(id int) *UserUpdateOne { + uuo.mutation.SetBestFriendID(id) + return uuo +} + +// SetNillableBestFriendID sets the best_friend edge to User by id if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableBestFriendID(id *int) *UserUpdateOne { + if id != nil { + uuo = uuo.SetBestFriendID(*id) + } + return uuo +} + +// SetBestFriend sets the best_friend edge to User. +func (uuo *UserUpdateOne) SetBestFriend(u *User) *UserUpdateOne { + return uuo.SetBestFriendID(u.ID) +} + +// RemoveCardIDs removes the cards edge to Card by ids. +func (uuo *UserUpdateOne) RemoveCardIDs(ids ...int) *UserUpdateOne { + uuo.mutation.RemoveCardIDs(ids...) + return uuo +} + +// RemoveCards removes cards edges to Card. +func (uuo *UserUpdateOne) RemoveCards(c ...*Card) *UserUpdateOne { + ids := make([]int, len(c)) + for i := range c { + ids[i] = c[i].ID + } + return uuo.RemoveCardIDs(ids...) +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (uuo *UserUpdateOne) RemoveFriendIDs(ids ...int) *UserUpdateOne { + uuo.mutation.RemoveFriendIDs(ids...) + return uuo +} + +// RemoveFriends removes friends edges to User. +func (uuo *UserUpdateOne) RemoveFriends(u ...*User) *UserUpdateOne { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return uuo.RemoveFriendIDs(ids...) +} + +// ClearBestFriend clears the best_friend edge to User. +func (uuo *UserUpdateOne) ClearBestFriend() *UserUpdateOne { + uuo.mutation.ClearBestFriend() + return uuo +} + +// Save executes the query and returns the updated entity. +func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX is like Save, but panics if an error occurs. +func (uuo *UserUpdateOne) SaveX(ctx context.Context) *User { + u, err := uuo.Save(ctx) + if err != nil { + panic(err) + } + return u +} + +// Exec executes the query on the entity. +func (uuo *UserUpdateOne) Exec(ctx context.Context) error { + _, err := uuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uuo *UserUpdateOne) ExecX(ctx context.Context) { + if err := uuo.Exec(ctx); err != nil { + panic(err) + } +} + +func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: user.Table, + Columns: user.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Name(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: user.FieldName, + }) + } + if nodes := uuo.mutation.RemovedCardsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CardsTable, + Columns: []string{user.CardsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.CardsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CardsTable, + Columns: []string{user.CardsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: card.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if nodes := uuo.mutation.RemovedFriendsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.FriendsTable, + Columns: user.FriendsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.FriendsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.FriendsTable, + Columns: user.FriendsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if uuo.mutation.BestFriendCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: user.BestFriendTable, + Columns: []string{user.BestFriendColumn}, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.BestFriendIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: user.BestFriendTable, + Columns: []string{user.BestFriendColumn}, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + u = &User{config: uuo.config} + _spec.Assign = u.assignValues + _spec.ScanValues = u.scanValues() + if err = sqlgraph.UpdateNode(ctx, uuo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{user.Label} + } else if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return nil, err + } + return u, nil +} diff --git a/entc/integration/hooks/hooks_test.go b/entc/integration/hooks/hooks_test.go new file mode 100644 index 000000000..490afb233 --- /dev/null +++ b/entc/integration/hooks/hooks_test.go @@ -0,0 +1,134 @@ +package hooks + +import ( + "context" + "fmt" + "testing" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/card" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/hook" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/migrate" + _ "github.com/facebookincubator/ent/entc/integration/hooks/ent/runtime" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/user" + + _ "github.com/mattn/go-sqlite3" + "github.com/stretchr/testify/require" +) + +func TestSchemaHooks(t *testing.T) { + ctx := context.Background() + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") + require.NoError(t, err) + defer client.Close() + require.NoError(t, client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true))) + _, err = client.Card.Create().SetNumber("123").Save(ctx) + require.EqualError(t, err, "card number is too short", "error is returned from hook") + crd := client.Card.Create().SetNumber("1234").SaveX(ctx) + require.Equal(t, "unknown", crd.Name, "name was set by hook") + client.Use(func(next ent.Mutator) ent.Mutator { + return hook.CardFunc(func(ctx context.Context, m *ent.CardMutation) (ent.Value, error) { + name, ok := m.Name() + require.True(t, !ok && name == "", "should be the first hook to execute") + return next.Mutate(ctx, m) + }) + }) + client.Card.Create().SetNumber("1234").SaveX(ctx) +} + +func TestRuntimeHooks(t *testing.T) { + ctx := context.Background() + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1", ent.Log(t.Log)) + require.NoError(t, err) + defer client.Close() + require.NoError(t, client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true))) + var calls int + client.Use(func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + calls++ + return next.Mutate(ctx, m) + }) + }) + client.Card.Create().SetNumber("1234").SaveX(ctx) + client.User.Create().SetName("a8m").SaveX(ctx) + require.Equal(t, 2, calls) + client = client.Debug() + client.Card.Create().SetNumber("1234").SaveX(ctx) + client.User.Create().SetName("a8m").SaveX(ctx) + require.Equal(t, 4, calls) +} + +func TestMutationClient(t *testing.T) { + ctx := context.Background() + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") + require.NoError(t, err) + defer client.Close() + require.NoError(t, client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true))) + client.Card.Use(func(next ent.Mutator) ent.Mutator { + return hook.CardFunc(func(ctx context.Context, m *ent.CardMutation) (ent.Value, error) { + id, _ := m.OwnerID() + usr := m.Client().User.GetX(ctx, id) + m.SetName(usr.Name) + return next.Mutate(ctx, m) + }) + }) + a8m := client.User.Create().SetName("a8m").SaveX(ctx) + crd := client.Card.Create().SetNumber("1234").SetOwner(a8m).SaveX(ctx) + require.Equal(t, a8m.Name, crd.Name) +} + +func TestMutationTx(t *testing.T) { + ctx := context.Background() + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") + require.NoError(t, err) + defer client.Close() + require.NoError(t, client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true))) + client.Card.Use(func(next ent.Mutator) ent.Mutator { + return hook.CardFunc(func(ctx context.Context, m *ent.CardMutation) (ent.Value, error) { + tx, err := m.Tx() + if err != nil { + return nil, err + } + if err := tx.Rollback(); err != nil { + return nil, err + } + return nil, fmt.Errorf("rolled back") + }) + }) + tx, err := client.Tx(ctx) + require.NoError(t, err) + a8m := tx.User.Create().SetName("a8m").SaveX(ctx) + crd, err := tx.Card.Create().SetNumber("1234").SetOwner(a8m).Save(ctx) + require.EqualError(t, err, "rolled back") + require.Nil(t, crd) + _, err = tx.Card.Query().All(ctx) + require.Error(t, err, "tx already rolled back") +} + +func TestDeletion(t *testing.T) { + ctx := context.Background() + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") + require.NoError(t, err) + defer client.Close() + require.NoError(t, client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true))) + client.User.Use(func(next ent.Mutator) ent.Mutator { + return hook.UserFunc(func(ctx context.Context, m *ent.UserMutation) (ent.Value, error) { + if !m.Op().Is(ent.OpDeleteOne) { + return next.Mutate(ctx, m) + } + id, ok := m.ID() + if !ok { + return nil, fmt.Errorf("missing id") + } + m.Client().Card.Delete().Where(card.HasOwnerWith(user.ID(id))).ExecX(ctx) + return next.Mutate(ctx, m) + }) + }) + a8m := client.User.Create().SetName("a8m").SaveX(ctx) + for i := 0; i < 5; i++ { + client.Card.Create().SetNumber(fmt.Sprintf("card-%d", i)).SetOwner(a8m).SaveX(ctx) + } + client.User.DeleteOne(a8m).ExecX(ctx) + require.Zero(t, client.User.Query().CountX(ctx)) + require.Zero(t, client.Card.Query().CountX(ctx)) +} diff --git a/entc/integration/hooks/main.go b/entc/integration/hooks/main.go new file mode 100644 index 000000000..e76cfbe2e --- /dev/null +++ b/entc/integration/hooks/main.go @@ -0,0 +1,69 @@ +//+build tests + +package main + +import ( + "context" + "fmt" + "io" + "os" + + "github.com/facebookincubator/ent/entc/integration/hooks/ent" + "github.com/facebookincubator/ent/entc/integration/hooks/ent/hook" + _ "github.com/facebookincubator/ent/entc/integration/hooks/ent/runtime" + _ "github.com/mattn/go-sqlite3" +) + +func main() { + ctx := context.Background() + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") + if err != nil { + panic(err) + } + if err := client.Schema.Create(ctx); err != nil { + panic(err) + } + client.Use(func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + fmt.Println("start") + defer fmt.Println("end") + return next.Mutate(ctx, m) + }) + }) + client.Card.Use(func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + fmt.Printf("Before Hook\tOp: %s\tType: %s\tConcreteType: %T\n", m.Op(), m.Type(), m) + defer fmt.Println("Done!") + if ns, ok := m.(interface{ SetName(string) }); ok { + ns.SetName("hook name") + } + return next.Mutate(ctx, m) + }) + }) + + client.Card.Use(func(next ent.Mutator) ent.Mutator { + return hook.CardFunc(func(ctx context.Context, m *ent.CardMutation) (ent.Value, error) { + fmt.Println("Concrete hook\t", m.Op()) + return next.Mutate(ctx, m) + }) + }) + client.Use(hook.On(LogWithConfig(os.Stdout), ent.OpUpdate|ent.OpCreate)) + + u := client.Card.Create().SetNumber("A").SaveX(ctx) + u.Update().SetName("Boring2").SaveX(ctx) + client.Card.Update().SetName("foo").SaveX(ctx) + client.Card.DeleteOneID(u.ID).ExecX(ctx) + client.Card.Delete().ExecX(ctx) +} + +func LogWithConfig(w io.Writer) ent.Hook { + if w == nil { + w = os.Stdout + } + return func(next ent.Mutator) ent.Mutator { + return hook.CardFunc(func(ctx context.Context, m *ent.CardMutation) (ent.Value, error) { + fmt.Fprintln(w, "Logging Hook:\t", m.Op()) + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/idtype/ent/client.go b/entc/integration/idtype/ent/client.go index 6c6ed50cd..b6fc7c69e 100644 --- a/entc/integration/idtype/ent/client.go +++ b/entc/integration/idtype/ent/client.go @@ -31,13 +31,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -65,7 +68,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -83,12 +86,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -96,6 +97,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -106,14 +113,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -123,12 +138,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id uint64) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -138,7 +156,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id uint64) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -201,3 +222,8 @@ func (c *UserClient) QueryFollowing(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/idtype/ent/config.go b/entc/integration/idtype/ent/config.go index dd64c4cf6..379610598 100644 --- a/entc/integration/idtype/ent/config.go +++ b/entc/integration/idtype/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/idtype/ent/ent.go b/entc/integration/idtype/ent/ent.go index 72c8fe4e6..2c95e167b 100644 --- a/entc/integration/idtype/ent/ent.go +++ b/entc/integration/idtype/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/idtype/ent/hook/hook.go b/entc/integration/idtype/ent/hook/hook.go new file mode 100644 index 000000000..3f79984cd --- /dev/null +++ b/entc/integration/idtype/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/idtype/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/idtype/ent/mutation.go b/entc/integration/idtype/ent/mutation.go new file mode 100644 index 000000000..1c2d454fb --- /dev/null +++ b/entc/integration/idtype/ent/mutation.go @@ -0,0 +1,447 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/idtype/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *uint64 + name *string + clearedFields map[string]bool + spouse *uint64 + clearedspouse bool + followers map[uint64]struct{} + removedfollowers map[uint64]struct{} + following map[uint64]struct{} + removedfollowing map[uint64]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id uint64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetSpouseID sets the spouse edge to User by id. +func (m *UserMutation) SetSpouseID(id uint64) { + m.spouse = &id +} + +// ClearSpouse clears the spouse edge to User. +func (m *UserMutation) ClearSpouse() { + m.clearedspouse = true +} + +// SpouseCleared returns if the edge spouse was cleared. +func (m *UserMutation) SpouseCleared() bool { + return m.clearedspouse +} + +// SpouseID returns the spouse id in the mutation. +func (m *UserMutation) SpouseID() (id uint64, exists bool) { + if m.spouse != nil { + return *m.spouse, true + } + return +} + +// SpouseIDs returns the spouse ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// SpouseID instead. It exists only for internal usage by the builders. +func (m *UserMutation) SpouseIDs() (ids []uint64) { + if id := m.spouse; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSpouse reset all changes of the spouse edge. +func (m *UserMutation) ResetSpouse() { + m.spouse = nil + m.clearedspouse = false +} + +// AddFollowerIDs adds the followers edge to User by ids. +func (m *UserMutation) AddFollowerIDs(ids ...uint64) { + if m.followers == nil { + m.followers = make(map[uint64]struct{}) + } + for i := range ids { + m.followers[ids[i]] = struct{}{} + } +} + +// RemoveFollowerIDs removes the followers edge to User by ids. +func (m *UserMutation) RemoveFollowerIDs(ids ...uint64) { + if m.removedfollowers == nil { + m.removedfollowers = make(map[uint64]struct{}) + } + for i := range ids { + m.removedfollowers[ids[i]] = struct{}{} + } +} + +// RemovedFollowers returns the removed ids of followers. +func (m *UserMutation) RemovedFollowersIDs() (ids []uint64) { + for id := range m.removedfollowers { + ids = append(ids, id) + } + return +} + +// FollowersIDs returns the followers ids in the mutation. +func (m *UserMutation) FollowersIDs() (ids []uint64) { + for id := range m.followers { + ids = append(ids, id) + } + return +} + +// ResetFollowers reset all changes of the followers edge. +func (m *UserMutation) ResetFollowers() { + m.followers = nil + m.removedfollowers = nil +} + +// AddFollowingIDs adds the following edge to User by ids. +func (m *UserMutation) AddFollowingIDs(ids ...uint64) { + if m.following == nil { + m.following = make(map[uint64]struct{}) + } + for i := range ids { + m.following[ids[i]] = struct{}{} + } +} + +// RemoveFollowingIDs removes the following edge to User by ids. +func (m *UserMutation) RemoveFollowingIDs(ids ...uint64) { + if m.removedfollowing == nil { + m.removedfollowing = make(map[uint64]struct{}) + } + for i := range ids { + m.removedfollowing[ids[i]] = struct{}{} + } +} + +// RemovedFollowing returns the removed ids of following. +func (m *UserMutation) RemovedFollowingIDs() (ids []uint64) { + for id := range m.removedfollowing { + ids = append(ids, id) + } + return +} + +// FollowingIDs returns the following ids in the mutation. +func (m *UserMutation) FollowingIDs() (ids []uint64) { + for id := range m.following { + ids = append(ids, id) + } + return +} + +// ResetFollowing reset all changes of the following edge. +func (m *UserMutation) ResetFollowing() { + m.following = nil + m.removedfollowing = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 3) + if m.spouse != nil { + edges = append(edges, user.EdgeSpouse) + } + if m.followers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.following != nil { + edges = append(edges, user.EdgeFollowing) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeSpouse: + if id := m.spouse; id != nil { + return []ent.Value{*id} + } + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.followers)) + for id := range m.followers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.following)) + for id := range m.following { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 3) + if m.removedfollowers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.removedfollowing != nil { + edges = append(edges, user.EdgeFollowing) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.removedfollowers)) + for id := range m.removedfollowers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.removedfollowing)) + for id := range m.removedfollowing { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 3) + if m.clearedspouse { + edges = append(edges, user.EdgeSpouse) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeSpouse: + return m.clearedspouse + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeSpouse: + m.ClearSpouse() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeSpouse: + m.ResetSpouse() + return nil + case user.EdgeFollowers: + m.ResetFollowers() + return nil + case user.EdgeFollowing: + m.ResetFollowing() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/idtype/ent/privacy/privacy.go b/entc/integration/idtype/ent/privacy/privacy.go new file mode 100644 index 000000000..85fe1952d --- /dev/null +++ b/entc/integration/idtype/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/idtype/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/idtype/ent/runtime.go b/entc/integration/idtype/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/entc/integration/idtype/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/entc/integration/idtype/ent/runtime/runtime.go b/entc/integration/idtype/ent/runtime/runtime.go new file mode 100644 index 000000000..d3961cf1d --- /dev/null +++ b/entc/integration/idtype/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/idtype/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/idtype/ent/tx.go b/entc/integration/idtype/ent/tx.go index 27a90fb98..fe30afd5c 100644 --- a/entc/integration/idtype/ent/tx.go +++ b/entc/integration/idtype/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/idtype/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/idtype/ent/user/user.go b/entc/integration/idtype/ent/user/user.go index 96930d4e1..4580f2668 100644 --- a/entc/integration/idtype/ent/user/user.go +++ b/entc/integration/idtype/ent/user/user.go @@ -10,10 +10,16 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeSpouse holds the string denoting the spouse edge name in mutations. + EdgeSpouse = "spouse" + // EdgeFollowers holds the string denoting the followers edge name in mutations. + EdgeFollowers = "followers" + // EdgeFollowing holds the string denoting the following edge name in mutations. + EdgeFollowing = "following" + // Table holds the table name of the user in the database. Table = "users" // SpouseTable is the table the holds the spouse relation/edge. diff --git a/entc/integration/idtype/ent/user_create.go b/entc/integration/idtype/ent/user_create.go index 927095ff9..e66bb3b1e 100644 --- a/entc/integration/idtype/ent/user_create.go +++ b/entc/integration/idtype/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/idtype/ent/user" @@ -18,24 +19,19 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - name *string - spouse map[uint64]struct{} - followers map[uint64]struct{} - following map[uint64]struct{} + mutation *UserMutation + hooks []Hook } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetSpouseID sets the spouse edge to User by id. func (uc *UserCreate) SetSpouseID(id uint64) *UserCreate { - if uc.spouse == nil { - uc.spouse = make(map[uint64]struct{}) - } - uc.spouse[id] = struct{}{} + uc.mutation.SetSpouseID(id) return uc } @@ -54,12 +50,7 @@ func (uc *UserCreate) SetSpouse(u *User) *UserCreate { // AddFollowerIDs adds the followers edge to User by ids. func (uc *UserCreate) AddFollowerIDs(ids ...uint64) *UserCreate { - if uc.followers == nil { - uc.followers = make(map[uint64]struct{}) - } - for i := range ids { - uc.followers[ids[i]] = struct{}{} - } + uc.mutation.AddFollowerIDs(ids...) return uc } @@ -74,12 +65,7 @@ func (uc *UserCreate) AddFollowers(u ...*User) *UserCreate { // AddFollowingIDs adds the following edge to User by ids. func (uc *UserCreate) AddFollowingIDs(ids ...uint64) *UserCreate { - if uc.following == nil { - uc.following = make(map[uint64]struct{}) - } - for i := range ids { - uc.following[ids[i]] = struct{}{} - } + uc.mutation.AddFollowingIDs(ids...) return uc } @@ -94,13 +80,33 @@ func (uc *UserCreate) AddFollowing(u ...*User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(uc.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -123,15 +129,15 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.spouse; len(nodes) > 0 { + if nodes := uc.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -145,12 +151,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.followers; len(nodes) > 0 { + if nodes := uc.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -164,12 +170,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.following; len(nodes) > 0 { + if nodes := uc.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -183,7 +189,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/idtype/ent/user_delete.go b/entc/integration/idtype/ent/user_delete.go index 375f1e79f..bd50dc91e 100644 --- a/entc/integration/idtype/ent/user_delete.go +++ b/entc/integration/idtype/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/idtype/ent/user_update.go b/entc/integration/idtype/ent/user_update.go index 26cd9bdf3..462705878 100644 --- a/entc/integration/idtype/ent/user_update.go +++ b/entc/integration/idtype/ent/user_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,14 +20,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - name *string - spouse map[uint64]struct{} - followers map[uint64]struct{} - following map[uint64]struct{} - clearedSpouse bool - removedFollowers map[uint64]struct{} - removedFollowing map[uint64]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -38,16 +33,13 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetSpouseID sets the spouse edge to User by id. func (uu *UserUpdate) SetSpouseID(id uint64) *UserUpdate { - if uu.spouse == nil { - uu.spouse = make(map[uint64]struct{}) - } - uu.spouse[id] = struct{}{} + uu.mutation.SetSpouseID(id) return uu } @@ -66,12 +58,7 @@ func (uu *UserUpdate) SetSpouse(u *User) *UserUpdate { // AddFollowerIDs adds the followers edge to User by ids. func (uu *UserUpdate) AddFollowerIDs(ids ...uint64) *UserUpdate { - if uu.followers == nil { - uu.followers = make(map[uint64]struct{}) - } - for i := range ids { - uu.followers[ids[i]] = struct{}{} - } + uu.mutation.AddFollowerIDs(ids...) return uu } @@ -86,12 +73,7 @@ func (uu *UserUpdate) AddFollowers(u ...*User) *UserUpdate { // AddFollowingIDs adds the following edge to User by ids. func (uu *UserUpdate) AddFollowingIDs(ids ...uint64) *UserUpdate { - if uu.following == nil { - uu.following = make(map[uint64]struct{}) - } - for i := range ids { - uu.following[ids[i]] = struct{}{} - } + uu.mutation.AddFollowingIDs(ids...) return uu } @@ -106,18 +88,13 @@ func (uu *UserUpdate) AddFollowing(u ...*User) *UserUpdate { // ClearSpouse clears the spouse edge to User. func (uu *UserUpdate) ClearSpouse() *UserUpdate { - uu.clearedSpouse = true + uu.mutation.ClearSpouse() return uu } // RemoveFollowerIDs removes the followers edge to User by ids. func (uu *UserUpdate) RemoveFollowerIDs(ids ...uint64) *UserUpdate { - if uu.removedFollowers == nil { - uu.removedFollowers = make(map[uint64]struct{}) - } - for i := range ids { - uu.removedFollowers[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowerIDs(ids...) return uu } @@ -132,12 +109,7 @@ func (uu *UserUpdate) RemoveFollowers(u ...*User) *UserUpdate { // RemoveFollowingIDs removes the following edge to User by ids. func (uu *UserUpdate) RemoveFollowingIDs(ids ...uint64) *UserUpdate { - if uu.removedFollowing == nil { - uu.removedFollowing = make(map[uint64]struct{}) - } - for i := range ids { - uu.removedFollowing[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowingIDs(ids...) return uu } @@ -152,10 +124,31 @@ func (uu *UserUpdate) RemoveFollowing(u ...*User) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if len(uu.spouse) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"spouse\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -198,14 +191,14 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if uu.clearedSpouse { + if uu.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -221,7 +214,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.spouse; len(nodes) > 0 { + if nodes := uu.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -235,12 +228,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFollowers; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -254,12 +247,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.followers; len(nodes) > 0 { + if nodes := uu.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -273,12 +266,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFollowing; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -292,12 +285,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.following; len(nodes) > 0 { + if nodes := uu.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -311,7 +304,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -330,28 +323,19 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id uint64 - name *string - spouse map[uint64]struct{} - followers map[uint64]struct{} - following map[uint64]struct{} - clearedSpouse bool - removedFollowers map[uint64]struct{} - removedFollowing map[uint64]struct{} + hooks []Hook + mutation *UserMutation } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetSpouseID sets the spouse edge to User by id. func (uuo *UserUpdateOne) SetSpouseID(id uint64) *UserUpdateOne { - if uuo.spouse == nil { - uuo.spouse = make(map[uint64]struct{}) - } - uuo.spouse[id] = struct{}{} + uuo.mutation.SetSpouseID(id) return uuo } @@ -370,12 +354,7 @@ func (uuo *UserUpdateOne) SetSpouse(u *User) *UserUpdateOne { // AddFollowerIDs adds the followers edge to User by ids. func (uuo *UserUpdateOne) AddFollowerIDs(ids ...uint64) *UserUpdateOne { - if uuo.followers == nil { - uuo.followers = make(map[uint64]struct{}) - } - for i := range ids { - uuo.followers[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowerIDs(ids...) return uuo } @@ -390,12 +369,7 @@ func (uuo *UserUpdateOne) AddFollowers(u ...*User) *UserUpdateOne { // AddFollowingIDs adds the following edge to User by ids. func (uuo *UserUpdateOne) AddFollowingIDs(ids ...uint64) *UserUpdateOne { - if uuo.following == nil { - uuo.following = make(map[uint64]struct{}) - } - for i := range ids { - uuo.following[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowingIDs(ids...) return uuo } @@ -410,18 +384,13 @@ func (uuo *UserUpdateOne) AddFollowing(u ...*User) *UserUpdateOne { // ClearSpouse clears the spouse edge to User. func (uuo *UserUpdateOne) ClearSpouse() *UserUpdateOne { - uuo.clearedSpouse = true + uuo.mutation.ClearSpouse() return uuo } // RemoveFollowerIDs removes the followers edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowerIDs(ids ...uint64) *UserUpdateOne { - if uuo.removedFollowers == nil { - uuo.removedFollowers = make(map[uint64]struct{}) - } - for i := range ids { - uuo.removedFollowers[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowerIDs(ids...) return uuo } @@ -436,12 +405,7 @@ func (uuo *UserUpdateOne) RemoveFollowers(u ...*User) *UserUpdateOne { // RemoveFollowingIDs removes the following edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowingIDs(ids ...uint64) *UserUpdateOne { - if uuo.removedFollowing == nil { - uuo.removedFollowing = make(map[uint64]struct{}) - } - for i := range ids { - uuo.removedFollowing[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowingIDs(ids...) return uuo } @@ -456,10 +420,31 @@ func (uuo *UserUpdateOne) RemoveFollowing(u ...*User) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if len(uuo.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -490,20 +475,24 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeUint64, Column: user.FieldID, }, }, } - if value := uuo.name; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if uuo.clearedSpouse { + if uuo.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -519,7 +508,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.spouse; len(nodes) > 0 { + if nodes := uuo.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -533,12 +522,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFollowers; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -552,12 +541,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.followers; len(nodes) > 0 { + if nodes := uuo.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -571,12 +560,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFollowing; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -590,12 +579,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.following; len(nodes) > 0 { + if nodes := uuo.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -609,7 +598,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/json/ent/client.go b/entc/integration/json/ent/client.go index f4f1d96eb..ebd750e57 100644 --- a/entc/integration/json/ent/client.go +++ b/entc/integration/json/ent/client.go @@ -30,13 +30,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -64,7 +67,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -82,12 +85,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -95,6 +96,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -105,14 +112,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -122,12 +137,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -137,7 +155,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -158,3 +179,8 @@ func (c *UserClient) GetX(ctx context.Context, id int) *User { } return u } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/json/ent/config.go b/entc/integration/json/ent/config.go index dd64c4cf6..379610598 100644 --- a/entc/integration/json/ent/config.go +++ b/entc/integration/json/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/json/ent/ent.go b/entc/integration/json/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/entc/integration/json/ent/ent.go +++ b/entc/integration/json/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/json/ent/hook/hook.go b/entc/integration/json/ent/hook/hook.go new file mode 100644 index 000000000..5f115b234 --- /dev/null +++ b/entc/integration/json/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/json/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/json/ent/mutation.go b/entc/integration/json/ent/mutation.go new file mode 100644 index 000000000..dbbeaadbc --- /dev/null +++ b/entc/integration/json/ent/mutation.go @@ -0,0 +1,545 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/json/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + url **url.URL + raw *json.RawMessage + dirs *[]http.Dir + ints *[]int + floats *[]float64 + strings *[]string + clearedFields map[string]bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetURL sets the url field. +func (m *UserMutation) SetURL(u *url.URL) { + m.url = &u +} + +// URL returns the url value in the mutation. +func (m *UserMutation) URL() (r *url.URL, exists bool) { + v := m.url + if v == nil { + return + } + return *v, true +} + +// ClearURL clears the value of url. +func (m *UserMutation) ClearURL() { + m.url = nil + m.clearedFields[user.FieldURL] = true +} + +// URLCleared returns if the field url was cleared in this mutation. +func (m *UserMutation) URLCleared() bool { + return m.clearedFields[user.FieldURL] +} + +// ResetURL reset all changes of the url field. +func (m *UserMutation) ResetURL() { + m.url = nil + delete(m.clearedFields, user.FieldURL) +} + +// SetRaw sets the raw field. +func (m *UserMutation) SetRaw(jm json.RawMessage) { + m.raw = &jm +} + +// Raw returns the raw value in the mutation. +func (m *UserMutation) Raw() (r json.RawMessage, exists bool) { + v := m.raw + if v == nil { + return + } + return *v, true +} + +// ClearRaw clears the value of raw. +func (m *UserMutation) ClearRaw() { + m.raw = nil + m.clearedFields[user.FieldRaw] = true +} + +// RawCleared returns if the field raw was cleared in this mutation. +func (m *UserMutation) RawCleared() bool { + return m.clearedFields[user.FieldRaw] +} + +// ResetRaw reset all changes of the raw field. +func (m *UserMutation) ResetRaw() { + m.raw = nil + delete(m.clearedFields, user.FieldRaw) +} + +// SetDirs sets the dirs field. +func (m *UserMutation) SetDirs(h []http.Dir) { + m.dirs = &h +} + +// Dirs returns the dirs value in the mutation. +func (m *UserMutation) Dirs() (r []http.Dir, exists bool) { + v := m.dirs + if v == nil { + return + } + return *v, true +} + +// ClearDirs clears the value of dirs. +func (m *UserMutation) ClearDirs() { + m.dirs = nil + m.clearedFields[user.FieldDirs] = true +} + +// DirsCleared returns if the field dirs was cleared in this mutation. +func (m *UserMutation) DirsCleared() bool { + return m.clearedFields[user.FieldDirs] +} + +// ResetDirs reset all changes of the dirs field. +func (m *UserMutation) ResetDirs() { + m.dirs = nil + delete(m.clearedFields, user.FieldDirs) +} + +// SetInts sets the ints field. +func (m *UserMutation) SetInts(i []int) { + m.ints = &i +} + +// Ints returns the ints value in the mutation. +func (m *UserMutation) Ints() (r []int, exists bool) { + v := m.ints + if v == nil { + return + } + return *v, true +} + +// ClearInts clears the value of ints. +func (m *UserMutation) ClearInts() { + m.ints = nil + m.clearedFields[user.FieldInts] = true +} + +// IntsCleared returns if the field ints was cleared in this mutation. +func (m *UserMutation) IntsCleared() bool { + return m.clearedFields[user.FieldInts] +} + +// ResetInts reset all changes of the ints field. +func (m *UserMutation) ResetInts() { + m.ints = nil + delete(m.clearedFields, user.FieldInts) +} + +// SetFloats sets the floats field. +func (m *UserMutation) SetFloats(f []float64) { + m.floats = &f +} + +// Floats returns the floats value in the mutation. +func (m *UserMutation) Floats() (r []float64, exists bool) { + v := m.floats + if v == nil { + return + } + return *v, true +} + +// ClearFloats clears the value of floats. +func (m *UserMutation) ClearFloats() { + m.floats = nil + m.clearedFields[user.FieldFloats] = true +} + +// FloatsCleared returns if the field floats was cleared in this mutation. +func (m *UserMutation) FloatsCleared() bool { + return m.clearedFields[user.FieldFloats] +} + +// ResetFloats reset all changes of the floats field. +func (m *UserMutation) ResetFloats() { + m.floats = nil + delete(m.clearedFields, user.FieldFloats) +} + +// SetStrings sets the strings field. +func (m *UserMutation) SetStrings(s []string) { + m.strings = &s +} + +// Strings returns the strings value in the mutation. +func (m *UserMutation) Strings() (r []string, exists bool) { + v := m.strings + if v == nil { + return + } + return *v, true +} + +// ClearStrings clears the value of strings. +func (m *UserMutation) ClearStrings() { + m.strings = nil + m.clearedFields[user.FieldStrings] = true +} + +// StringsCleared returns if the field strings was cleared in this mutation. +func (m *UserMutation) StringsCleared() bool { + return m.clearedFields[user.FieldStrings] +} + +// ResetStrings reset all changes of the strings field. +func (m *UserMutation) ResetStrings() { + m.strings = nil + delete(m.clearedFields, user.FieldStrings) +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 6) + if m.url != nil { + fields = append(fields, user.FieldURL) + } + if m.raw != nil { + fields = append(fields, user.FieldRaw) + } + if m.dirs != nil { + fields = append(fields, user.FieldDirs) + } + if m.ints != nil { + fields = append(fields, user.FieldInts) + } + if m.floats != nil { + fields = append(fields, user.FieldFloats) + } + if m.strings != nil { + fields = append(fields, user.FieldStrings) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldURL: + return m.URL() + case user.FieldRaw: + return m.Raw() + case user.FieldDirs: + return m.Dirs() + case user.FieldInts: + return m.Ints() + case user.FieldFloats: + return m.Floats() + case user.FieldStrings: + return m.Strings() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldURL: + v, ok := value.(*url.URL) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetURL(v) + return nil + case user.FieldRaw: + v, ok := value.(json.RawMessage) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRaw(v) + return nil + case user.FieldDirs: + v, ok := value.([]http.Dir) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDirs(v) + return nil + case user.FieldInts: + v, ok := value.([]int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInts(v) + return nil + case user.FieldFloats: + v, ok := value.([]float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFloats(v) + return nil + case user.FieldStrings: + v, ok := value.([]string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetStrings(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[user.FieldURL] { + fields = append(fields, user.FieldURL) + } + if m.clearedFields[user.FieldRaw] { + fields = append(fields, user.FieldRaw) + } + if m.clearedFields[user.FieldDirs] { + fields = append(fields, user.FieldDirs) + } + if m.clearedFields[user.FieldInts] { + fields = append(fields, user.FieldInts) + } + if m.clearedFields[user.FieldFloats] { + fields = append(fields, user.FieldFloats) + } + if m.clearedFields[user.FieldStrings] { + fields = append(fields, user.FieldStrings) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + switch name { + case user.FieldURL: + m.ClearURL() + return nil + case user.FieldRaw: + m.ClearRaw() + return nil + case user.FieldDirs: + m.ClearDirs() + return nil + case user.FieldInts: + m.ClearInts() + return nil + case user.FieldFloats: + m.ClearFloats() + return nil + case user.FieldStrings: + m.ClearStrings() + return nil + } + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldURL: + m.ResetURL() + return nil + case user.FieldRaw: + m.ResetRaw() + return nil + case user.FieldDirs: + m.ResetDirs() + return nil + case user.FieldInts: + m.ResetInts() + return nil + case user.FieldFloats: + m.ResetFloats() + return nil + case user.FieldStrings: + m.ResetStrings() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/json/ent/privacy/privacy.go b/entc/integration/json/ent/privacy/privacy.go new file mode 100644 index 000000000..2b15514b1 --- /dev/null +++ b/entc/integration/json/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/json/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/json/ent/runtime.go b/entc/integration/json/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/entc/integration/json/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/entc/integration/json/ent/runtime/runtime.go b/entc/integration/json/ent/runtime/runtime.go new file mode 100644 index 000000000..0ca2404ef --- /dev/null +++ b/entc/integration/json/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/json/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/json/ent/tx.go b/entc/integration/json/ent/tx.go index 9fc21a265..fe30afd5c 100644 --- a/entc/integration/json/ent/tx.go +++ b/entc/integration/json/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/json/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/json/ent/user/user.go b/entc/integration/json/ent/user/user.go index 25b9b5b44..dca70cece 100644 --- a/entc/integration/json/ent/user/user.go +++ b/entc/integration/json/ent/user/user.go @@ -10,18 +10,12 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldURL holds the string denoting the url vertex property in the database. - FieldURL = "url" - // FieldRaw holds the string denoting the raw vertex property in the database. - FieldRaw = "raw" - // FieldDirs holds the string denoting the dirs vertex property in the database. - FieldDirs = "dirs" - // FieldInts holds the string denoting the ints vertex property in the database. - FieldInts = "ints" - // FieldFloats holds the string denoting the floats vertex property in the database. - FieldFloats = "floats" - // FieldStrings holds the string denoting the strings vertex property in the database. + FieldID = "id" // FieldURL holds the string denoting the url vertex property in the database. + FieldURL = "url" // FieldRaw holds the string denoting the raw vertex property in the database. + FieldRaw = "raw" // FieldDirs holds the string denoting the dirs vertex property in the database. + FieldDirs = "dirs" // FieldInts holds the string denoting the ints vertex property in the database. + FieldInts = "ints" // FieldFloats holds the string denoting the floats vertex property in the database. + FieldFloats = "floats" // FieldStrings holds the string denoting the strings vertex property in the database. FieldStrings = "strings" // Table holds the table name of the user in the database. diff --git a/entc/integration/json/ent/user_create.go b/entc/integration/json/ent/user_create.go index 725b84e1d..42627d35a 100644 --- a/entc/integration/json/ent/user_create.go +++ b/entc/integration/json/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "encoding/json" + "fmt" "net/http" "net/url" @@ -20,53 +21,72 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - url **url.URL - raw *json.RawMessage - dirs *[]http.Dir - ints *[]int - floats *[]float64 - strings *[]string + mutation *UserMutation + hooks []Hook } // SetURL sets the url field. func (uc *UserCreate) SetURL(u *url.URL) *UserCreate { - uc.url = &u + uc.mutation.SetURL(u) return uc } // SetRaw sets the raw field. func (uc *UserCreate) SetRaw(jm json.RawMessage) *UserCreate { - uc.raw = &jm + uc.mutation.SetRaw(jm) return uc } // SetDirs sets the dirs field. func (uc *UserCreate) SetDirs(h []http.Dir) *UserCreate { - uc.dirs = &h + uc.mutation.SetDirs(h) return uc } // SetInts sets the ints field. func (uc *UserCreate) SetInts(i []int) *UserCreate { - uc.ints = &i + uc.mutation.SetInts(i) return uc } // SetFloats sets the floats field. func (uc *UserCreate) SetFloats(f []float64) *UserCreate { - uc.floats = &f + uc.mutation.SetFloats(f) return uc } // SetStrings sets the strings field. func (uc *UserCreate) SetStrings(s []string) *UserCreate { - uc.strings = &s + uc.mutation.SetStrings(s) return uc } // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -89,53 +109,53 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.url; value != nil { + if value, ok := uc.mutation.URL(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldURL, }) - u.URL = *value + u.URL = value } - if value := uc.raw; value != nil { + if value, ok := uc.mutation.Raw(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldRaw, }) - u.Raw = *value + u.Raw = value } - if value := uc.dirs; value != nil { + if value, ok := uc.mutation.Dirs(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldDirs, }) - u.Dirs = *value + u.Dirs = value } - if value := uc.ints; value != nil { + if value, ok := uc.mutation.Ints(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldInts, }) - u.Ints = *value + u.Ints = value } - if value := uc.floats; value != nil { + if value, ok := uc.mutation.Floats(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldFloats, }) - u.Floats = *value + u.Floats = value } - if value := uc.strings; value != nil { + if value, ok := uc.mutation.Strings(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldStrings, }) - u.Strings = *value + u.Strings = value } if err := sqlgraph.CreateNode(ctx, uc.driver, _spec); err != nil { if cerr, ok := isSQLConstraintError(err); ok { diff --git a/entc/integration/json/ent/user_delete.go b/entc/integration/json/ent/user_delete.go index 6e3cb0c55..2faeba197 100644 --- a/entc/integration/json/ent/user_delete.go +++ b/entc/integration/json/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/json/ent/user_update.go b/entc/integration/json/ent/user_update.go index 2cd7ef170..3a8493143 100644 --- a/entc/integration/json/ent/user_update.go +++ b/entc/integration/json/ent/user_update.go @@ -9,6 +9,7 @@ package ent import ( "context" "encoding/json" + "fmt" "net/http" "net/url" @@ -22,19 +23,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - url **url.URL - clearurl bool - raw *json.RawMessage - clearraw bool - dirs *[]http.Dir - cleardirs bool - ints *[]int - clearints bool - floats *[]float64 - clearfloats bool - strings *[]string - clearstrings bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -45,85 +36,102 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetURL sets the url field. func (uu *UserUpdate) SetURL(u *url.URL) *UserUpdate { - uu.url = &u + uu.mutation.SetURL(u) return uu } // ClearURL clears the value of url. func (uu *UserUpdate) ClearURL() *UserUpdate { - uu.url = nil - uu.clearurl = true + uu.mutation.ClearURL() return uu } // SetRaw sets the raw field. func (uu *UserUpdate) SetRaw(jm json.RawMessage) *UserUpdate { - uu.raw = &jm + uu.mutation.SetRaw(jm) return uu } // ClearRaw clears the value of raw. func (uu *UserUpdate) ClearRaw() *UserUpdate { - uu.raw = nil - uu.clearraw = true + uu.mutation.ClearRaw() return uu } // SetDirs sets the dirs field. func (uu *UserUpdate) SetDirs(h []http.Dir) *UserUpdate { - uu.dirs = &h + uu.mutation.SetDirs(h) return uu } // ClearDirs clears the value of dirs. func (uu *UserUpdate) ClearDirs() *UserUpdate { - uu.dirs = nil - uu.cleardirs = true + uu.mutation.ClearDirs() return uu } // SetInts sets the ints field. func (uu *UserUpdate) SetInts(i []int) *UserUpdate { - uu.ints = &i + uu.mutation.SetInts(i) return uu } // ClearInts clears the value of ints. func (uu *UserUpdate) ClearInts() *UserUpdate { - uu.ints = nil - uu.clearints = true + uu.mutation.ClearInts() return uu } // SetFloats sets the floats field. func (uu *UserUpdate) SetFloats(f []float64) *UserUpdate { - uu.floats = &f + uu.mutation.SetFloats(f) return uu } // ClearFloats clears the value of floats. func (uu *UserUpdate) ClearFloats() *UserUpdate { - uu.floats = nil - uu.clearfloats = true + uu.mutation.ClearFloats() return uu } // SetStrings sets the strings field. func (uu *UserUpdate) SetStrings(s []string) *UserUpdate { - uu.strings = &s + uu.mutation.SetStrings(s) return uu } // ClearStrings clears the value of strings. func (uu *UserUpdate) ClearStrings() *UserUpdate { - uu.strings = nil - uu.clearstrings = true + uu.mutation.ClearStrings() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -166,79 +174,79 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.url; value != nil { + if value, ok := uu.mutation.URL(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldURL, }) } - if uu.clearurl { + if uu.mutation.URLCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldURL, }) } - if value := uu.raw; value != nil { + if value, ok := uu.mutation.Raw(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldRaw, }) } - if uu.clearraw { + if uu.mutation.RawCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldRaw, }) } - if value := uu.dirs; value != nil { + if value, ok := uu.mutation.Dirs(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldDirs, }) } - if uu.cleardirs { + if uu.mutation.DirsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldDirs, }) } - if value := uu.ints; value != nil { + if value, ok := uu.mutation.Ints(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldInts, }) } - if uu.clearints { + if uu.mutation.IntsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldInts, }) } - if value := uu.floats; value != nil { + if value, ok := uu.mutation.Floats(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldFloats, }) } - if uu.clearfloats { + if uu.mutation.FloatsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldFloats, }) } - if value := uu.strings; value != nil { + if value, ok := uu.mutation.Strings(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldStrings, }) } - if uu.clearstrings { + if uu.mutation.StringsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldStrings, @@ -258,102 +266,108 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - url **url.URL - clearurl bool - raw *json.RawMessage - clearraw bool - dirs *[]http.Dir - cleardirs bool - ints *[]int - clearints bool - floats *[]float64 - clearfloats bool - strings *[]string - clearstrings bool + hooks []Hook + mutation *UserMutation } // SetURL sets the url field. func (uuo *UserUpdateOne) SetURL(u *url.URL) *UserUpdateOne { - uuo.url = &u + uuo.mutation.SetURL(u) return uuo } // ClearURL clears the value of url. func (uuo *UserUpdateOne) ClearURL() *UserUpdateOne { - uuo.url = nil - uuo.clearurl = true + uuo.mutation.ClearURL() return uuo } // SetRaw sets the raw field. func (uuo *UserUpdateOne) SetRaw(jm json.RawMessage) *UserUpdateOne { - uuo.raw = &jm + uuo.mutation.SetRaw(jm) return uuo } // ClearRaw clears the value of raw. func (uuo *UserUpdateOne) ClearRaw() *UserUpdateOne { - uuo.raw = nil - uuo.clearraw = true + uuo.mutation.ClearRaw() return uuo } // SetDirs sets the dirs field. func (uuo *UserUpdateOne) SetDirs(h []http.Dir) *UserUpdateOne { - uuo.dirs = &h + uuo.mutation.SetDirs(h) return uuo } // ClearDirs clears the value of dirs. func (uuo *UserUpdateOne) ClearDirs() *UserUpdateOne { - uuo.dirs = nil - uuo.cleardirs = true + uuo.mutation.ClearDirs() return uuo } // SetInts sets the ints field. func (uuo *UserUpdateOne) SetInts(i []int) *UserUpdateOne { - uuo.ints = &i + uuo.mutation.SetInts(i) return uuo } // ClearInts clears the value of ints. func (uuo *UserUpdateOne) ClearInts() *UserUpdateOne { - uuo.ints = nil - uuo.clearints = true + uuo.mutation.ClearInts() return uuo } // SetFloats sets the floats field. func (uuo *UserUpdateOne) SetFloats(f []float64) *UserUpdateOne { - uuo.floats = &f + uuo.mutation.SetFloats(f) return uuo } // ClearFloats clears the value of floats. func (uuo *UserUpdateOne) ClearFloats() *UserUpdateOne { - uuo.floats = nil - uuo.clearfloats = true + uuo.mutation.ClearFloats() return uuo } // SetStrings sets the strings field. func (uuo *UserUpdateOne) SetStrings(s []string) *UserUpdateOne { - uuo.strings = &s + uuo.mutation.SetStrings(s) return uuo } // ClearStrings clears the value of strings. func (uuo *UserUpdateOne) ClearStrings() *UserUpdateOne { - uuo.strings = nil - uuo.clearstrings = true + uuo.mutation.ClearStrings() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -384,85 +398,89 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.url; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.URL(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldURL, }) } - if uuo.clearurl { + if uuo.mutation.URLCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldURL, }) } - if value := uuo.raw; value != nil { + if value, ok := uuo.mutation.Raw(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldRaw, }) } - if uuo.clearraw { + if uuo.mutation.RawCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldRaw, }) } - if value := uuo.dirs; value != nil { + if value, ok := uuo.mutation.Dirs(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldDirs, }) } - if uuo.cleardirs { + if uuo.mutation.DirsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldDirs, }) } - if value := uuo.ints; value != nil { + if value, ok := uuo.mutation.Ints(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldInts, }) } - if uuo.clearints { + if uuo.mutation.IntsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldInts, }) } - if value := uuo.floats; value != nil { + if value, ok := uuo.mutation.Floats(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldFloats, }) } - if uuo.clearfloats { + if uuo.mutation.FloatsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldFloats, }) } - if value := uuo.strings; value != nil { + if value, ok := uuo.mutation.Strings(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeJSON, - Value: *value, + Value: value, Column: user.FieldStrings, }) } - if uuo.clearstrings { + if uuo.mutation.StringsCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeJSON, Column: user.FieldStrings, diff --git a/entc/integration/migrate/entv1/car/car.go b/entc/integration/migrate/entv1/car/car.go index 66d2152e9..0b3f4bd20 100644 --- a/entc/integration/migrate/entv1/car/car.go +++ b/entc/integration/migrate/entv1/car/car.go @@ -12,6 +12,9 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the car in the database. Table = "cars" // OwnerTable is the table the holds the owner relation/edge. diff --git a/entc/integration/migrate/entv1/car_create.go b/entc/integration/migrate/entv1/car_create.go index dc872285d..cc8636cb1 100644 --- a/entc/integration/migrate/entv1/car_create.go +++ b/entc/integration/migrate/entv1/car_create.go @@ -8,7 +8,7 @@ package entv1 import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/migrate/entv1/car" @@ -19,15 +19,13 @@ import ( // CarCreate is the builder for creating a Car entity. type CarCreate struct { config - owner map[int]struct{} + mutation *CarMutation + hooks []Hook } // SetOwnerID sets the owner edge to User by id. func (cc *CarCreate) SetOwnerID(id int) *CarCreate { - if cc.owner == nil { - cc.owner = make(map[int]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -46,10 +44,30 @@ func (cc *CarCreate) SetOwner(u *User) *CarCreate { // Save creates the Car in the database. func (cc *CarCreate) Save(ctx context.Context) (*Car, error) { - if len(cc.owner) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Car + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } } - return cc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -72,7 +90,7 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, } ) - if nodes := cc.owner; len(nodes) > 0 { + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -86,7 +104,7 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/migrate/entv1/car_delete.go b/entc/integration/migrate/entv1/car_delete.go index 42ec694a4..756b3a1fb 100644 --- a/entc/integration/migrate/entv1/car_delete.go +++ b/entc/integration/migrate/entv1/car_delete.go @@ -8,6 +8,7 @@ package entv1 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CarDelete is the builder for deleting a Car entity. type CarDelete struct { config + hooks []Hook + mutation *CarMutation predicates []predicate.Car } @@ -30,7 +33,30 @@ func (cd *CarDelete) Where(ps ...predicate.Car) *CarDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CarDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/migrate/entv1/car_update.go b/entc/integration/migrate/entv1/car_update.go index dd6cf8db3..0f51dadf3 100644 --- a/entc/integration/migrate/entv1/car_update.go +++ b/entc/integration/migrate/entv1/car_update.go @@ -8,7 +8,7 @@ package entv1 import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,9 +21,9 @@ import ( // CarUpdate is the builder for updating Car entities. type CarUpdate struct { config - owner map[int]struct{} - clearedOwner bool - predicates []predicate.Car + hooks []Hook + mutation *CarMutation + predicates []predicate.Car } // Where adds a new predicate for the builder. @@ -34,10 +34,7 @@ func (cu *CarUpdate) Where(ps ...predicate.Car) *CarUpdate { // SetOwnerID sets the owner edge to User by id. func (cu *CarUpdate) SetOwnerID(id int) *CarUpdate { - if cu.owner == nil { - cu.owner = make(map[int]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -56,16 +53,37 @@ func (cu *CarUpdate) SetOwner(u *User) *CarUpdate { // ClearOwner clears the owner edge to User. func (cu *CarUpdate) ClearOwner() *CarUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CarUpdate) Save(ctx context.Context) (int, error) { - if len(cu.owner) > 1 { - return 0, errors.New("entv1: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } } - return cu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -108,7 +126,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -124,7 +142,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.owner; len(nodes) > 0 { + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -138,7 +156,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -157,17 +175,13 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { // CarUpdateOne is the builder for updating a single Car entity. type CarUpdateOne struct { config - id int - owner map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *CarMutation } // SetOwnerID sets the owner edge to User by id. func (cuo *CarUpdateOne) SetOwnerID(id int) *CarUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[int]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -186,16 +200,37 @@ func (cuo *CarUpdateOne) SetOwner(u *User) *CarUpdateOne { // ClearOwner clears the owner edge to User. func (cuo *CarUpdateOne) ClearOwner() *CarUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // Save executes the query and returns the updated entity. func (cuo *CarUpdateOne) Save(ctx context.Context) (*Car, error) { - if len(cuo.owner) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Car + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } } - return cuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -226,13 +261,17 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { Table: car.Table, Columns: car.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeInt, Column: car.FieldID, }, }, } - if cuo.clearedOwner { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Car.ID for update") + } + _spec.Node.ID.Value = id + if cuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -248,7 +287,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.owner; len(nodes) > 0 { + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -262,7 +301,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/migrate/entv1/client.go b/entc/integration/migrate/entv1/client.go index dce1af90c..032bff346 100644 --- a/entc/integration/migrate/entv1/client.go +++ b/entc/integration/migrate/entv1/client.go @@ -34,14 +34,17 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Car: NewCarClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Car = NewCarClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -69,7 +72,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("entv1: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Car: NewCarClient(cfg), @@ -88,13 +91,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Car: NewCarClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -102,6 +102,13 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Car.Use(hooks...) + c.User.Use(hooks...) +} + // CarClient is a client for the Car schema. type CarClient struct { config @@ -112,14 +119,22 @@ func NewCarClient(c config) *CarClient { return &CarClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `car.Hooks(f(g(h())))`. +func (c *CarClient) Use(hooks ...Hook) { + c.hooks.Car = append(c.hooks.Car, hooks...) +} + // Create returns a create builder for Car. func (c *CarClient) Create() *CarCreate { - return &CarCreate{config: c.config} + mutation := newCarMutation(c.config, OpCreate) + return &CarCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Car. func (c *CarClient) Update() *CarUpdate { - return &CarUpdate{config: c.config} + mutation := newCarMutation(c.config, OpUpdate) + return &CarUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -129,12 +144,15 @@ func (c *CarClient) UpdateOne(ca *Car) *CarUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CarClient) UpdateOneID(id int) *CarUpdateOne { - return &CarUpdateOne{config: c.config, id: id} + mutation := newCarMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CarUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Car. func (c *CarClient) Delete() *CarDelete { - return &CarDelete{config: c.config} + mutation := newCarMutation(c.config, OpDelete) + return &CarDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -144,7 +162,10 @@ func (c *CarClient) DeleteOne(ca *Car) *CarDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CarClient) DeleteOneID(id int) *CarDeleteOne { - return &CarDeleteOne{c.Delete().Where(car.ID(id))} + builder := c.Delete().Where(car.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CarDeleteOne{builder} } // Create returns a query builder for Car. @@ -180,6 +201,11 @@ func (c *CarClient) QueryOwner(ca *Car) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *CarClient) Hooks() []Hook { + return c.hooks.Car +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -190,14 +216,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -207,12 +241,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -222,7 +259,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -299,3 +339,8 @@ func (c *UserClient) QueryCar(u *User) *CarQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/migrate/entv1/config.go b/entc/integration/migrate/entv1/config.go index 446e8734d..5f770e682 100644 --- a/entc/integration/migrate/entv1/config.go +++ b/entc/integration/migrate/entv1/config.go @@ -7,6 +7,7 @@ package entv1 import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,14 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Car []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/migrate/entv1/ent.go b/entc/integration/migrate/entv1/ent.go index d8d756c53..843c8b7b2 100644 --- a/entc/integration/migrate/entv1/ent.go +++ b/entc/integration/migrate/entv1/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/migrate/entv1/hook/hook.go b/entc/integration/migrate/entv1/hook/hook.go new file mode 100644 index 000000000..77208d09d --- /dev/null +++ b/entc/integration/migrate/entv1/hook/hook.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent" +) + +// The CarFunc type is an adapter to allow the use of ordinary +// function as Car mutator. +type CarFunc func(context.Context, *ent.CarMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CarFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CarMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/migrate/entv1/mutation.go b/entc/integration/migrate/entv1/mutation.go new file mode 100644 index 000000000..b8ae40c54 --- /dev/null +++ b/entc/integration/migrate/entv1/mutation.go @@ -0,0 +1,1085 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package entv1 + +import ( + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/migrate/entv1/car" + "github.com/facebookincubator/ent/entc/integration/migrate/entv1/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCar = "Car" + TypeUser = "User" +) + +// CarMutation represents an operation that mutate the Cars +// nodes in the graph. +type CarMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*CarMutation)(nil) + +// newCarMutation creates new mutation for $n.Name. +func newCarMutation(c config, op Op) *CarMutation { + return &CarMutation{ + config: c, + op: op, + typ: TypeCar, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CarMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CarMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("entv1: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CarMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CarMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CarMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CarMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CarMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CarMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CarMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *CarMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Car). +func (m *CarMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CarMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CarMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CarMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CarMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Car numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CarMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CarMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CarMutation) ClearField(name string) error { + return fmt.Errorf("unknown Car nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CarMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CarMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CarMutation) AddedIDs(name string) []ent.Value { + switch name { + case car.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CarMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CarMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CarMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CarMutation) EdgeCleared(name string) bool { + switch name { + case car.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CarMutation) ClearEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Car unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CarMutation) ResetEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Car edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int32 + addage *int32 + name *string + nickname *string + address *string + renamed *string + blob *[]byte + state *user.State + clearedFields map[string]bool + parent *int + clearedparent bool + children map[int]struct{} + removedchildren map[int]struct{} + spouse *int + clearedspouse bool + car *int + clearedcar bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("entv1: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that, this +// operation is accepted only on User creation. +func (m *UserMutation) SetID(id int) { + m.id = &id +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int32) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int32, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int32) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int32, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetNickname sets the nickname field. +func (m *UserMutation) SetNickname(s string) { + m.nickname = &s +} + +// Nickname returns the nickname value in the mutation. +func (m *UserMutation) Nickname() (r string, exists bool) { + v := m.nickname + if v == nil { + return + } + return *v, true +} + +// ResetNickname reset all changes of the nickname field. +func (m *UserMutation) ResetNickname() { + m.nickname = nil +} + +// SetAddress sets the address field. +func (m *UserMutation) SetAddress(s string) { + m.address = &s +} + +// Address returns the address value in the mutation. +func (m *UserMutation) Address() (r string, exists bool) { + v := m.address + if v == nil { + return + } + return *v, true +} + +// ClearAddress clears the value of address. +func (m *UserMutation) ClearAddress() { + m.address = nil + m.clearedFields[user.FieldAddress] = true +} + +// AddressCleared returns if the field address was cleared in this mutation. +func (m *UserMutation) AddressCleared() bool { + return m.clearedFields[user.FieldAddress] +} + +// ResetAddress reset all changes of the address field. +func (m *UserMutation) ResetAddress() { + m.address = nil + delete(m.clearedFields, user.FieldAddress) +} + +// SetRenamed sets the renamed field. +func (m *UserMutation) SetRenamed(s string) { + m.renamed = &s +} + +// Renamed returns the renamed value in the mutation. +func (m *UserMutation) Renamed() (r string, exists bool) { + v := m.renamed + if v == nil { + return + } + return *v, true +} + +// ClearRenamed clears the value of renamed. +func (m *UserMutation) ClearRenamed() { + m.renamed = nil + m.clearedFields[user.FieldRenamed] = true +} + +// RenamedCleared returns if the field renamed was cleared in this mutation. +func (m *UserMutation) RenamedCleared() bool { + return m.clearedFields[user.FieldRenamed] +} + +// ResetRenamed reset all changes of the renamed field. +func (m *UserMutation) ResetRenamed() { + m.renamed = nil + delete(m.clearedFields, user.FieldRenamed) +} + +// SetBlob sets the blob field. +func (m *UserMutation) SetBlob(b []byte) { + m.blob = &b +} + +// Blob returns the blob value in the mutation. +func (m *UserMutation) Blob() (r []byte, exists bool) { + v := m.blob + if v == nil { + return + } + return *v, true +} + +// ClearBlob clears the value of blob. +func (m *UserMutation) ClearBlob() { + m.blob = nil + m.clearedFields[user.FieldBlob] = true +} + +// BlobCleared returns if the field blob was cleared in this mutation. +func (m *UserMutation) BlobCleared() bool { + return m.clearedFields[user.FieldBlob] +} + +// ResetBlob reset all changes of the blob field. +func (m *UserMutation) ResetBlob() { + m.blob = nil + delete(m.clearedFields, user.FieldBlob) +} + +// SetState sets the state field. +func (m *UserMutation) SetState(u user.State) { + m.state = &u +} + +// State returns the state value in the mutation. +func (m *UserMutation) State() (r user.State, exists bool) { + v := m.state + if v == nil { + return + } + return *v, true +} + +// ClearState clears the value of state. +func (m *UserMutation) ClearState() { + m.state = nil + m.clearedFields[user.FieldState] = true +} + +// StateCleared returns if the field state was cleared in this mutation. +func (m *UserMutation) StateCleared() bool { + return m.clearedFields[user.FieldState] +} + +// ResetState reset all changes of the state field. +func (m *UserMutation) ResetState() { + m.state = nil + delete(m.clearedFields, user.FieldState) +} + +// SetParentID sets the parent edge to User by id. +func (m *UserMutation) SetParentID(id int) { + m.parent = &id +} + +// ClearParent clears the parent edge to User. +func (m *UserMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared returns if the edge parent was cleared. +func (m *UserMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the parent id in the mutation. +func (m *UserMutation) ParentID() (id int, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the parent ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *UserMutation) ParentIDs() (ids []int) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent reset all changes of the parent edge. +func (m *UserMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// AddChildIDs adds the children edge to User by ids. +func (m *UserMutation) AddChildIDs(ids ...int) { + if m.children == nil { + m.children = make(map[int]struct{}) + } + for i := range ids { + m.children[ids[i]] = struct{}{} + } +} + +// RemoveChildIDs removes the children edge to User by ids. +func (m *UserMutation) RemoveChildIDs(ids ...int) { + if m.removedchildren == nil { + m.removedchildren = make(map[int]struct{}) + } + for i := range ids { + m.removedchildren[ids[i]] = struct{}{} + } +} + +// RemovedChildren returns the removed ids of children. +func (m *UserMutation) RemovedChildrenIDs() (ids []int) { + for id := range m.removedchildren { + ids = append(ids, id) + } + return +} + +// ChildrenIDs returns the children ids in the mutation. +func (m *UserMutation) ChildrenIDs() (ids []int) { + for id := range m.children { + ids = append(ids, id) + } + return +} + +// ResetChildren reset all changes of the children edge. +func (m *UserMutation) ResetChildren() { + m.children = nil + m.removedchildren = nil +} + +// SetSpouseID sets the spouse edge to User by id. +func (m *UserMutation) SetSpouseID(id int) { + m.spouse = &id +} + +// ClearSpouse clears the spouse edge to User. +func (m *UserMutation) ClearSpouse() { + m.clearedspouse = true +} + +// SpouseCleared returns if the edge spouse was cleared. +func (m *UserMutation) SpouseCleared() bool { + return m.clearedspouse +} + +// SpouseID returns the spouse id in the mutation. +func (m *UserMutation) SpouseID() (id int, exists bool) { + if m.spouse != nil { + return *m.spouse, true + } + return +} + +// SpouseIDs returns the spouse ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// SpouseID instead. It exists only for internal usage by the builders. +func (m *UserMutation) SpouseIDs() (ids []int) { + if id := m.spouse; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSpouse reset all changes of the spouse edge. +func (m *UserMutation) ResetSpouse() { + m.spouse = nil + m.clearedspouse = false +} + +// SetCarID sets the car edge to Car by id. +func (m *UserMutation) SetCarID(id int) { + m.car = &id +} + +// ClearCar clears the car edge to Car. +func (m *UserMutation) ClearCar() { + m.clearedcar = true +} + +// CarCleared returns if the edge car was cleared. +func (m *UserMutation) CarCleared() bool { + return m.clearedcar +} + +// CarID returns the car id in the mutation. +func (m *UserMutation) CarID() (id int, exists bool) { + if m.car != nil { + return *m.car, true + } + return +} + +// CarIDs returns the car ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// CarID instead. It exists only for internal usage by the builders. +func (m *UserMutation) CarIDs() (ids []int) { + if id := m.car; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetCar reset all changes of the car edge. +func (m *UserMutation) ResetCar() { + m.car = nil + m.clearedcar = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 7) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + if m.nickname != nil { + fields = append(fields, user.FieldNickname) + } + if m.address != nil { + fields = append(fields, user.FieldAddress) + } + if m.renamed != nil { + fields = append(fields, user.FieldRenamed) + } + if m.blob != nil { + fields = append(fields, user.FieldBlob) + } + if m.state != nil { + fields = append(fields, user.FieldState) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + case user.FieldNickname: + return m.Nickname() + case user.FieldAddress: + return m.Address() + case user.FieldRenamed: + return m.Renamed() + case user.FieldBlob: + return m.Blob() + case user.FieldState: + return m.State() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case user.FieldNickname: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNickname(v) + return nil + case user.FieldAddress: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAddress(v) + return nil + case user.FieldRenamed: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRenamed(v) + return nil + case user.FieldBlob: + v, ok := value.([]byte) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBlob(v) + return nil + case user.FieldState: + v, ok := value.(user.State) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetState(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int32) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[user.FieldAddress] { + fields = append(fields, user.FieldAddress) + } + if m.clearedFields[user.FieldRenamed] { + fields = append(fields, user.FieldRenamed) + } + if m.clearedFields[user.FieldBlob] { + fields = append(fields, user.FieldBlob) + } + if m.clearedFields[user.FieldState] { + fields = append(fields, user.FieldState) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + switch name { + case user.FieldAddress: + m.ClearAddress() + return nil + case user.FieldRenamed: + m.ClearRenamed() + return nil + case user.FieldBlob: + m.ClearBlob() + return nil + case user.FieldState: + m.ClearState() + return nil + } + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + case user.FieldNickname: + m.ResetNickname() + return nil + case user.FieldAddress: + m.ResetAddress() + return nil + case user.FieldRenamed: + m.ResetRenamed() + return nil + case user.FieldBlob: + m.ResetBlob() + return nil + case user.FieldState: + m.ResetState() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 4) + if m.parent != nil { + edges = append(edges, user.EdgeParent) + } + if m.children != nil { + edges = append(edges, user.EdgeChildren) + } + if m.spouse != nil { + edges = append(edges, user.EdgeSpouse) + } + if m.car != nil { + edges = append(edges, user.EdgeCar) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.children)) + for id := range m.children { + ids = append(ids, id) + } + return ids + case user.EdgeSpouse: + if id := m.spouse; id != nil { + return []ent.Value{*id} + } + case user.EdgeCar: + if id := m.car; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 4) + if m.removedchildren != nil { + edges = append(edges, user.EdgeChildren) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeChildren: + ids := make([]ent.Value, 0, len(m.removedchildren)) + for id := range m.removedchildren { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 4) + if m.clearedparent { + edges = append(edges, user.EdgeParent) + } + if m.clearedspouse { + edges = append(edges, user.EdgeSpouse) + } + if m.clearedcar { + edges = append(edges, user.EdgeCar) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeParent: + return m.clearedparent + case user.EdgeSpouse: + return m.clearedspouse + case user.EdgeCar: + return m.clearedcar + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeParent: + m.ClearParent() + return nil + case user.EdgeSpouse: + m.ClearSpouse() + return nil + case user.EdgeCar: + m.ClearCar() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeParent: + m.ResetParent() + return nil + case user.EdgeChildren: + m.ResetChildren() + return nil + case user.EdgeSpouse: + m.ResetSpouse() + return nil + case user.EdgeCar: + m.ResetCar() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/migrate/entv1/privacy/privacy.go b/entc/integration/migrate/entv1/privacy/privacy.go new file mode 100644 index 000000000..15064ea05 --- /dev/null +++ b/entc/integration/migrate/entv1/privacy/privacy.go @@ -0,0 +1,195 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CarReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CarReadRuleFunc func(context.Context, *ent.Car) error + +// EvalRead calls f(ctx, v). +func (f CarReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Car); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Car", v) +} + +// The CarWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CarWriteRuleFunc func(context.Context, *ent.CarMutation) error + +// EvalWrite calls f(ctx, m). +func (f CarWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CarMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CarMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/migrate/entv1/runtime.go b/entc/integration/migrate/entv1/runtime.go new file mode 100644 index 000000000..74102091b --- /dev/null +++ b/entc/integration/migrate/entv1/runtime.go @@ -0,0 +1,24 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package entv1 + +import ( + "github.com/facebookincubator/ent/entc/integration/migrate/entv1/schema" + + "github.com/facebookincubator/ent/entc/integration/migrate/entv1/user" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + userFields := schema.User{}.Fields() + // userDescName is the schema descriptor for name field. + userDescName := userFields[2].Descriptor() + // user.NameValidator is a validator for the "name" field. It is called by the builders before save. + user.NameValidator = userDescName.Validators[0].(func(string) error) +} diff --git a/entc/integration/migrate/entv1/runtime/runtime.go b/entc/integration/migrate/entv1/runtime/runtime.go new file mode 100644 index 000000000..f5a544de8 --- /dev/null +++ b/entc/integration/migrate/entv1/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/migrate/entv1/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/migrate/entv1/tx.go b/entc/integration/migrate/entv1/tx.go index d91fe7fc5..f08b6275b 100644 --- a/entc/integration/migrate/entv1/tx.go +++ b/entc/integration/migrate/entv1/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/migrate/entv1/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -34,12 +33,14 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Car: NewCarClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Car = NewCarClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/migrate/entv1/user/user.go b/entc/integration/migrate/entv1/user/user.go index 9b6b4c0f1..06b33f1e4 100644 --- a/entc/integration/migrate/entv1/user/user.go +++ b/entc/integration/migrate/entv1/user/user.go @@ -8,29 +8,29 @@ package user import ( "fmt" - - "github.com/facebookincubator/ent/entc/integration/migrate/entv1/schema" ) const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "oid" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" - // FieldNickname holds the string denoting the nickname vertex property in the database. - FieldNickname = "nickname" - // FieldAddress holds the string denoting the address vertex property in the database. - FieldAddress = "address" - // FieldRenamed holds the string denoting the renamed vertex property in the database. - FieldRenamed = "renamed" - // FieldBlob holds the string denoting the blob vertex property in the database. - FieldBlob = "blob" - // FieldState holds the string denoting the state vertex property in the database. - FieldState = "state" + FieldID = "oid" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldNickname holds the string denoting the nickname vertex property in the database. + FieldNickname = "nickname" // FieldAddress holds the string denoting the address vertex property in the database. + FieldAddress = "address" // FieldRenamed holds the string denoting the renamed vertex property in the database. + FieldRenamed = "renamed" // FieldBlob holds the string denoting the blob vertex property in the database. + FieldBlob = "blob" // FieldState holds the string denoting the state vertex property in the database. + FieldState = "state" + + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" + // EdgeChildren holds the string denoting the children edge name in mutations. + EdgeChildren = "children" + // EdgeSpouse holds the string denoting the spouse edge name in mutations. + EdgeSpouse = "spouse" + // EdgeCar holds the string denoting the car edge name in mutations. + EdgeCar = "car" // Table holds the table name of the user in the database. Table = "users" @@ -74,12 +74,8 @@ var ForeignKeys = []string{ } var ( - fields = schema.User{}.Fields() - - // descName is the schema descriptor for name field. - descName = fields[2].Descriptor() // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator = descName.Validators[0].(func(string) error) + NameValidator func(string) error ) // State defines the type for the state enum field. diff --git a/entc/integration/migrate/entv1/user_create.go b/entc/integration/migrate/entv1/user_create.go index 2b8e51a96..4712a5a1d 100644 --- a/entc/integration/migrate/entv1/user_create.go +++ b/entc/integration/migrate/entv1/user_create.go @@ -20,41 +20,31 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - id *int - age *int32 - name *string - nickname *string - address *string - renamed *string - blob *[]byte - state *user.State - parent map[int]struct{} - children map[int]struct{} - spouse map[int]struct{} - car map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int32) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetNickname sets the nickname field. func (uc *UserCreate) SetNickname(s string) *UserCreate { - uc.nickname = &s + uc.mutation.SetNickname(s) return uc } // SetAddress sets the address field. func (uc *UserCreate) SetAddress(s string) *UserCreate { - uc.address = &s + uc.mutation.SetAddress(s) return uc } @@ -68,7 +58,7 @@ func (uc *UserCreate) SetNillableAddress(s *string) *UserCreate { // SetRenamed sets the renamed field. func (uc *UserCreate) SetRenamed(s string) *UserCreate { - uc.renamed = &s + uc.mutation.SetRenamed(s) return uc } @@ -82,13 +72,13 @@ func (uc *UserCreate) SetNillableRenamed(s *string) *UserCreate { // SetBlob sets the blob field. func (uc *UserCreate) SetBlob(b []byte) *UserCreate { - uc.blob = &b + uc.mutation.SetBlob(b) return uc } // SetState sets the state field. func (uc *UserCreate) SetState(u user.State) *UserCreate { - uc.state = &u + uc.mutation.SetState(u) return uc } @@ -102,16 +92,13 @@ func (uc *UserCreate) SetNillableState(u *user.State) *UserCreate { // SetID sets the id field. func (uc *UserCreate) SetID(i int) *UserCreate { - uc.id = &i + uc.mutation.SetID(i) return uc } // SetParentID sets the parent edge to User by id. func (uc *UserCreate) SetParentID(id int) *UserCreate { - if uc.parent == nil { - uc.parent = make(map[int]struct{}) - } - uc.parent[id] = struct{}{} + uc.mutation.SetParentID(id) return uc } @@ -130,12 +117,7 @@ func (uc *UserCreate) SetParent(u *User) *UserCreate { // AddChildIDs adds the children edge to User by ids. func (uc *UserCreate) AddChildIDs(ids ...int) *UserCreate { - if uc.children == nil { - uc.children = make(map[int]struct{}) - } - for i := range ids { - uc.children[ids[i]] = struct{}{} - } + uc.mutation.AddChildIDs(ids...) return uc } @@ -150,10 +132,7 @@ func (uc *UserCreate) AddChildren(u ...*User) *UserCreate { // SetSpouseID sets the spouse edge to User by id. func (uc *UserCreate) SetSpouseID(id int) *UserCreate { - if uc.spouse == nil { - uc.spouse = make(map[int]struct{}) - } - uc.spouse[id] = struct{}{} + uc.mutation.SetSpouseID(id) return uc } @@ -172,10 +151,7 @@ func (uc *UserCreate) SetSpouse(u *User) *UserCreate { // SetCarID sets the car edge to Car by id. func (uc *UserCreate) SetCarID(id int) *UserCreate { - if uc.car == nil { - uc.car = make(map[int]struct{}) - } - uc.car[id] = struct{}{} + uc.mutation.SetCarID(id) return uc } @@ -194,33 +170,49 @@ func (uc *UserCreate) SetCar(c *Car) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("entv1: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("entv1: missing required field \"name\"") } - if err := user.NameValidator(*uc.name); err != nil { - return nil, fmt.Errorf("entv1: validator failed for field \"name\": %v", err) + if v, ok := uc.mutation.Name(); ok { + if err := user.NameValidator(v); err != nil { + return nil, fmt.Errorf("entv1: validator failed for field \"name\": %v", err) + } } - if uc.nickname == nil { + if _, ok := uc.mutation.Nickname(); !ok { return nil, errors.New("entv1: missing required field \"nickname\"") } - if uc.state != nil { - if err := user.StateValidator(*uc.state); err != nil { + if v, ok := uc.mutation.State(); ok { + if err := user.StateValidator(v); err != nil { return nil, fmt.Errorf("entv1: validator failed for field \"state\": %v", err) } } - if len(uc.parent) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"parent\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - if len(uc.spouse) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"spouse\"") - } - if len(uc.car) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"car\"") - } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -243,67 +235,67 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.id; value != nil { - u.ID = *value - _spec.ID.Value = *value + if id, ok := uc.mutation.ID(); ok { + u.ID = id + _spec.ID.Value = id } - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if value := uc.nickname; value != nil { + if value, ok := uc.mutation.Nickname(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) - u.Nickname = *value + u.Nickname = value } - if value := uc.address; value != nil { + if value, ok := uc.mutation.Address(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldAddress, }) - u.Address = *value + u.Address = value } - if value := uc.renamed; value != nil { + if value, ok := uc.mutation.Renamed(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldRenamed, }) - u.Renamed = *value + u.Renamed = value } - if value := uc.blob; value != nil { + if value, ok := uc.mutation.Blob(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBlob, }) - u.Blob = *value + u.Blob = value } - if value := uc.state; value != nil { + if value, ok := uc.mutation.State(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldState, }) - u.State = *value + u.State = value } - if nodes := uc.parent; len(nodes) > 0 { + if nodes := uc.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -317,12 +309,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.children; len(nodes) > 0 { + if nodes := uc.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -336,12 +328,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.spouse; len(nodes) > 0 { + if nodes := uc.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -355,12 +347,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.car; len(nodes) > 0 { + if nodes := uc.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -374,7 +366,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/migrate/entv1/user_delete.go b/entc/integration/migrate/entv1/user_delete.go index ad2abb694..6c1445657 100644 --- a/entc/integration/migrate/entv1/user_delete.go +++ b/entc/integration/migrate/entv1/user_delete.go @@ -8,6 +8,7 @@ package entv1 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/migrate/entv1/user_update.go b/entc/integration/migrate/entv1/user_update.go index ad768e317..704ce706e 100644 --- a/entc/integration/migrate/entv1/user_update.go +++ b/entc/integration/migrate/entv1/user_update.go @@ -8,7 +8,6 @@ package entv1 import ( "context" - "errors" "fmt" "github.com/facebookincubator/ent/dialect/sql" @@ -22,27 +21,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int32 - addage *int32 - name *string - nickname *string - address *string - clearaddress bool - renamed *string - clearrenamed bool - blob *[]byte - clearblob bool - state *user.State - clearstate bool - parent map[int]struct{} - children map[int]struct{} - spouse map[int]struct{} - car map[int]struct{} - clearedParent bool - removedChildren map[int]struct{} - clearedSpouse bool - clearedCar bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -53,36 +34,32 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int32) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int32) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetNickname sets the nickname field. func (uu *UserUpdate) SetNickname(s string) *UserUpdate { - uu.nickname = &s + uu.mutation.SetNickname(s) return uu } // SetAddress sets the address field. func (uu *UserUpdate) SetAddress(s string) *UserUpdate { - uu.address = &s + uu.mutation.SetAddress(s) return uu } @@ -96,14 +73,13 @@ func (uu *UserUpdate) SetNillableAddress(s *string) *UserUpdate { // ClearAddress clears the value of address. func (uu *UserUpdate) ClearAddress() *UserUpdate { - uu.address = nil - uu.clearaddress = true + uu.mutation.ClearAddress() return uu } // SetRenamed sets the renamed field. func (uu *UserUpdate) SetRenamed(s string) *UserUpdate { - uu.renamed = &s + uu.mutation.SetRenamed(s) return uu } @@ -117,27 +93,25 @@ func (uu *UserUpdate) SetNillableRenamed(s *string) *UserUpdate { // ClearRenamed clears the value of renamed. func (uu *UserUpdate) ClearRenamed() *UserUpdate { - uu.renamed = nil - uu.clearrenamed = true + uu.mutation.ClearRenamed() return uu } // SetBlob sets the blob field. func (uu *UserUpdate) SetBlob(b []byte) *UserUpdate { - uu.blob = &b + uu.mutation.SetBlob(b) return uu } // ClearBlob clears the value of blob. func (uu *UserUpdate) ClearBlob() *UserUpdate { - uu.blob = nil - uu.clearblob = true + uu.mutation.ClearBlob() return uu } // SetState sets the state field. func (uu *UserUpdate) SetState(u user.State) *UserUpdate { - uu.state = &u + uu.mutation.SetState(u) return uu } @@ -151,17 +125,13 @@ func (uu *UserUpdate) SetNillableState(u *user.State) *UserUpdate { // ClearState clears the value of state. func (uu *UserUpdate) ClearState() *UserUpdate { - uu.state = nil - uu.clearstate = true + uu.mutation.ClearState() return uu } // SetParentID sets the parent edge to User by id. func (uu *UserUpdate) SetParentID(id int) *UserUpdate { - if uu.parent == nil { - uu.parent = make(map[int]struct{}) - } - uu.parent[id] = struct{}{} + uu.mutation.SetParentID(id) return uu } @@ -180,12 +150,7 @@ func (uu *UserUpdate) SetParent(u *User) *UserUpdate { // AddChildIDs adds the children edge to User by ids. func (uu *UserUpdate) AddChildIDs(ids ...int) *UserUpdate { - if uu.children == nil { - uu.children = make(map[int]struct{}) - } - for i := range ids { - uu.children[ids[i]] = struct{}{} - } + uu.mutation.AddChildIDs(ids...) return uu } @@ -200,10 +165,7 @@ func (uu *UserUpdate) AddChildren(u ...*User) *UserUpdate { // SetSpouseID sets the spouse edge to User by id. func (uu *UserUpdate) SetSpouseID(id int) *UserUpdate { - if uu.spouse == nil { - uu.spouse = make(map[int]struct{}) - } - uu.spouse[id] = struct{}{} + uu.mutation.SetSpouseID(id) return uu } @@ -222,10 +184,7 @@ func (uu *UserUpdate) SetSpouse(u *User) *UserUpdate { // SetCarID sets the car edge to Car by id. func (uu *UserUpdate) SetCarID(id int) *UserUpdate { - if uu.car == nil { - uu.car = make(map[int]struct{}) - } - uu.car[id] = struct{}{} + uu.mutation.SetCarID(id) return uu } @@ -244,18 +203,13 @@ func (uu *UserUpdate) SetCar(c *Car) *UserUpdate { // ClearParent clears the parent edge to User. func (uu *UserUpdate) ClearParent() *UserUpdate { - uu.clearedParent = true + uu.mutation.ClearParent() return uu } // RemoveChildIDs removes the children edge to User by ids. func (uu *UserUpdate) RemoveChildIDs(ids ...int) *UserUpdate { - if uu.removedChildren == nil { - uu.removedChildren = make(map[int]struct{}) - } - for i := range ids { - uu.removedChildren[ids[i]] = struct{}{} - } + uu.mutation.RemoveChildIDs(ids...) return uu } @@ -270,38 +224,53 @@ func (uu *UserUpdate) RemoveChildren(u ...*User) *UserUpdate { // ClearSpouse clears the spouse edge to User. func (uu *UserUpdate) ClearSpouse() *UserUpdate { - uu.clearedSpouse = true + uu.mutation.ClearSpouse() return uu } // ClearCar clears the car edge to Car. func (uu *UserUpdate) ClearCar() *UserUpdate { - uu.clearedCar = true + uu.mutation.ClearCar() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if uu.name != nil { - if err := user.NameValidator(*uu.name); err != nil { + if v, ok := uu.mutation.Name(); ok { + if err := user.NameValidator(v); err != nil { return 0, fmt.Errorf("entv1: validator failed for field \"name\": %v", err) } } - if uu.state != nil { - if err := user.StateValidator(*uu.state); err != nil { + if v, ok := uu.mutation.State(); ok { + if err := user.StateValidator(v); err != nil { return 0, fmt.Errorf("entv1: validator failed for field \"state\": %v", err) } } - if len(uu.parent) > 1 { - return 0, errors.New("entv1: multiple assignments on a unique edge \"parent\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - if len(uu.spouse) > 1 { - return 0, errors.New("entv1: multiple assignments on a unique edge \"spouse\"") - } - if len(uu.car) > 1 { - return 0, errors.New("entv1: multiple assignments on a unique edge \"car\"") - } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -344,87 +313,87 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if value := uu.nickname; value != nil { + if value, ok := uu.mutation.Nickname(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) } - if value := uu.address; value != nil { + if value, ok := uu.mutation.Address(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldAddress, }) } - if uu.clearaddress { + if uu.mutation.AddressCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldAddress, }) } - if value := uu.renamed; value != nil { + if value, ok := uu.mutation.Renamed(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldRenamed, }) } - if uu.clearrenamed { + if uu.mutation.RenamedCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldRenamed, }) } - if value := uu.blob; value != nil { + if value, ok := uu.mutation.Blob(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBlob, }) } - if uu.clearblob { + if uu.mutation.BlobCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeBytes, Column: user.FieldBlob, }) } - if value := uu.state; value != nil { + if value, ok := uu.mutation.State(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldState, }) } - if uu.clearstate { + if uu.mutation.StateCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeEnum, Column: user.FieldState, }) } - if uu.clearedParent { + if uu.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -440,7 +409,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.parent; len(nodes) > 0 { + if nodes := uu.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -454,12 +423,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedChildren; len(nodes) > 0 { + if nodes := uu.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -473,12 +442,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.children; len(nodes) > 0 { + if nodes := uu.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -492,12 +461,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedSpouse { + if uu.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -513,7 +482,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.spouse; len(nodes) > 0 { + if nodes := uu.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -527,12 +496,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedCar { + if uu.mutation.CarCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -548,7 +517,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.car; len(nodes) > 0 { + if nodes := uu.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -562,7 +531,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -581,61 +550,38 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int32 - addage *int32 - name *string - nickname *string - address *string - clearaddress bool - renamed *string - clearrenamed bool - blob *[]byte - clearblob bool - state *user.State - clearstate bool - parent map[int]struct{} - children map[int]struct{} - spouse map[int]struct{} - car map[int]struct{} - clearedParent bool - removedChildren map[int]struct{} - clearedSpouse bool - clearedCar bool + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int32) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int32) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetNickname sets the nickname field. func (uuo *UserUpdateOne) SetNickname(s string) *UserUpdateOne { - uuo.nickname = &s + uuo.mutation.SetNickname(s) return uuo } // SetAddress sets the address field. func (uuo *UserUpdateOne) SetAddress(s string) *UserUpdateOne { - uuo.address = &s + uuo.mutation.SetAddress(s) return uuo } @@ -649,14 +595,13 @@ func (uuo *UserUpdateOne) SetNillableAddress(s *string) *UserUpdateOne { // ClearAddress clears the value of address. func (uuo *UserUpdateOne) ClearAddress() *UserUpdateOne { - uuo.address = nil - uuo.clearaddress = true + uuo.mutation.ClearAddress() return uuo } // SetRenamed sets the renamed field. func (uuo *UserUpdateOne) SetRenamed(s string) *UserUpdateOne { - uuo.renamed = &s + uuo.mutation.SetRenamed(s) return uuo } @@ -670,27 +615,25 @@ func (uuo *UserUpdateOne) SetNillableRenamed(s *string) *UserUpdateOne { // ClearRenamed clears the value of renamed. func (uuo *UserUpdateOne) ClearRenamed() *UserUpdateOne { - uuo.renamed = nil - uuo.clearrenamed = true + uuo.mutation.ClearRenamed() return uuo } // SetBlob sets the blob field. func (uuo *UserUpdateOne) SetBlob(b []byte) *UserUpdateOne { - uuo.blob = &b + uuo.mutation.SetBlob(b) return uuo } // ClearBlob clears the value of blob. func (uuo *UserUpdateOne) ClearBlob() *UserUpdateOne { - uuo.blob = nil - uuo.clearblob = true + uuo.mutation.ClearBlob() return uuo } // SetState sets the state field. func (uuo *UserUpdateOne) SetState(u user.State) *UserUpdateOne { - uuo.state = &u + uuo.mutation.SetState(u) return uuo } @@ -704,17 +647,13 @@ func (uuo *UserUpdateOne) SetNillableState(u *user.State) *UserUpdateOne { // ClearState clears the value of state. func (uuo *UserUpdateOne) ClearState() *UserUpdateOne { - uuo.state = nil - uuo.clearstate = true + uuo.mutation.ClearState() return uuo } // SetParentID sets the parent edge to User by id. func (uuo *UserUpdateOne) SetParentID(id int) *UserUpdateOne { - if uuo.parent == nil { - uuo.parent = make(map[int]struct{}) - } - uuo.parent[id] = struct{}{} + uuo.mutation.SetParentID(id) return uuo } @@ -733,12 +672,7 @@ func (uuo *UserUpdateOne) SetParent(u *User) *UserUpdateOne { // AddChildIDs adds the children edge to User by ids. func (uuo *UserUpdateOne) AddChildIDs(ids ...int) *UserUpdateOne { - if uuo.children == nil { - uuo.children = make(map[int]struct{}) - } - for i := range ids { - uuo.children[ids[i]] = struct{}{} - } + uuo.mutation.AddChildIDs(ids...) return uuo } @@ -753,10 +687,7 @@ func (uuo *UserUpdateOne) AddChildren(u ...*User) *UserUpdateOne { // SetSpouseID sets the spouse edge to User by id. func (uuo *UserUpdateOne) SetSpouseID(id int) *UserUpdateOne { - if uuo.spouse == nil { - uuo.spouse = make(map[int]struct{}) - } - uuo.spouse[id] = struct{}{} + uuo.mutation.SetSpouseID(id) return uuo } @@ -775,10 +706,7 @@ func (uuo *UserUpdateOne) SetSpouse(u *User) *UserUpdateOne { // SetCarID sets the car edge to Car by id. func (uuo *UserUpdateOne) SetCarID(id int) *UserUpdateOne { - if uuo.car == nil { - uuo.car = make(map[int]struct{}) - } - uuo.car[id] = struct{}{} + uuo.mutation.SetCarID(id) return uuo } @@ -797,18 +725,13 @@ func (uuo *UserUpdateOne) SetCar(c *Car) *UserUpdateOne { // ClearParent clears the parent edge to User. func (uuo *UserUpdateOne) ClearParent() *UserUpdateOne { - uuo.clearedParent = true + uuo.mutation.ClearParent() return uuo } // RemoveChildIDs removes the children edge to User by ids. func (uuo *UserUpdateOne) RemoveChildIDs(ids ...int) *UserUpdateOne { - if uuo.removedChildren == nil { - uuo.removedChildren = make(map[int]struct{}) - } - for i := range ids { - uuo.removedChildren[ids[i]] = struct{}{} - } + uuo.mutation.RemoveChildIDs(ids...) return uuo } @@ -823,38 +746,53 @@ func (uuo *UserUpdateOne) RemoveChildren(u ...*User) *UserUpdateOne { // ClearSpouse clears the spouse edge to User. func (uuo *UserUpdateOne) ClearSpouse() *UserUpdateOne { - uuo.clearedSpouse = true + uuo.mutation.ClearSpouse() return uuo } // ClearCar clears the car edge to Car. func (uuo *UserUpdateOne) ClearCar() *UserUpdateOne { - uuo.clearedCar = true + uuo.mutation.ClearCar() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if uuo.name != nil { - if err := user.NameValidator(*uuo.name); err != nil { + if v, ok := uuo.mutation.Name(); ok { + if err := user.NameValidator(v); err != nil { return nil, fmt.Errorf("entv1: validator failed for field \"name\": %v", err) } } - if uuo.state != nil { - if err := user.StateValidator(*uuo.state); err != nil { + if v, ok := uuo.mutation.State(); ok { + if err := user.StateValidator(v); err != nil { return nil, fmt.Errorf("entv1: validator failed for field \"state\": %v", err) } } - if len(uuo.parent) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"parent\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - if len(uuo.spouse) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"spouse\"") - } - if len(uuo.car) > 1 { - return nil, errors.New("entv1: multiple assignments on a unique edge \"car\"") - } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -885,93 +823,97 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt32, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if value := uuo.nickname; value != nil { + if value, ok := uuo.mutation.Nickname(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) } - if value := uuo.address; value != nil { + if value, ok := uuo.mutation.Address(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldAddress, }) } - if uuo.clearaddress { + if uuo.mutation.AddressCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldAddress, }) } - if value := uuo.renamed; value != nil { + if value, ok := uuo.mutation.Renamed(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldRenamed, }) } - if uuo.clearrenamed { + if uuo.mutation.RenamedCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldRenamed, }) } - if value := uuo.blob; value != nil { + if value, ok := uuo.mutation.Blob(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBlob, }) } - if uuo.clearblob { + if uuo.mutation.BlobCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeBytes, Column: user.FieldBlob, }) } - if value := uuo.state; value != nil { + if value, ok := uuo.mutation.State(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldState, }) } - if uuo.clearstate { + if uuo.mutation.StateCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeEnum, Column: user.FieldState, }) } - if uuo.clearedParent { + if uuo.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -987,7 +929,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.parent; len(nodes) > 0 { + if nodes := uuo.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -1001,12 +943,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedChildren; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -1020,12 +962,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.children; len(nodes) > 0 { + if nodes := uuo.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -1039,12 +981,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedSpouse { + if uuo.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1060,7 +1002,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.spouse; len(nodes) > 0 { + if nodes := uuo.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1074,12 +1016,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedCar { + if uuo.mutation.CarCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1095,7 +1037,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.car; len(nodes) > 0 { + if nodes := uuo.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -1109,7 +1051,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/migrate/entv2/car/car.go b/entc/integration/migrate/entv2/car/car.go index 66d2152e9..0b3f4bd20 100644 --- a/entc/integration/migrate/entv2/car/car.go +++ b/entc/integration/migrate/entv2/car/car.go @@ -12,6 +12,9 @@ const ( // FieldID holds the string denoting the id field in the database. FieldID = "id" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the car in the database. Table = "cars" // OwnerTable is the table the holds the owner relation/edge. diff --git a/entc/integration/migrate/entv2/car_create.go b/entc/integration/migrate/entv2/car_create.go index 40ea4f317..a84542c87 100644 --- a/entc/integration/migrate/entv2/car_create.go +++ b/entc/integration/migrate/entv2/car_create.go @@ -8,7 +8,7 @@ package entv2 import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/migrate/entv2/car" @@ -19,15 +19,13 @@ import ( // CarCreate is the builder for creating a Car entity. type CarCreate struct { config - owner map[int]struct{} + mutation *CarMutation + hooks []Hook } // SetOwnerID sets the owner edge to User by id. func (cc *CarCreate) SetOwnerID(id int) *CarCreate { - if cc.owner == nil { - cc.owner = make(map[int]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -46,10 +44,30 @@ func (cc *CarCreate) SetOwner(u *User) *CarCreate { // Save creates the Car in the database. func (cc *CarCreate) Save(ctx context.Context) (*Car, error) { - if len(cc.owner) > 1 { - return nil, errors.New("entv2: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Car + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } } - return cc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -72,7 +90,7 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, } ) - if nodes := cc.owner; len(nodes) > 0 { + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -86,7 +104,7 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/migrate/entv2/car_delete.go b/entc/integration/migrate/entv2/car_delete.go index 7e171ecc9..8e89b5a10 100644 --- a/entc/integration/migrate/entv2/car_delete.go +++ b/entc/integration/migrate/entv2/car_delete.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CarDelete is the builder for deleting a Car entity. type CarDelete struct { config + hooks []Hook + mutation *CarMutation predicates []predicate.Car } @@ -30,7 +33,30 @@ func (cd *CarDelete) Where(ps ...predicate.Car) *CarDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CarDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/migrate/entv2/car_update.go b/entc/integration/migrate/entv2/car_update.go index f8c4794fe..613fadbe9 100644 --- a/entc/integration/migrate/entv2/car_update.go +++ b/entc/integration/migrate/entv2/car_update.go @@ -8,7 +8,7 @@ package entv2 import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,9 +21,9 @@ import ( // CarUpdate is the builder for updating Car entities. type CarUpdate struct { config - owner map[int]struct{} - clearedOwner bool - predicates []predicate.Car + hooks []Hook + mutation *CarMutation + predicates []predicate.Car } // Where adds a new predicate for the builder. @@ -34,10 +34,7 @@ func (cu *CarUpdate) Where(ps ...predicate.Car) *CarUpdate { // SetOwnerID sets the owner edge to User by id. func (cu *CarUpdate) SetOwnerID(id int) *CarUpdate { - if cu.owner == nil { - cu.owner = make(map[int]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -56,16 +53,37 @@ func (cu *CarUpdate) SetOwner(u *User) *CarUpdate { // ClearOwner clears the owner edge to User. func (cu *CarUpdate) ClearOwner() *CarUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CarUpdate) Save(ctx context.Context) (int, error) { - if len(cu.owner) > 1 { - return 0, errors.New("entv2: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } } - return cu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -108,7 +126,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -124,7 +142,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.owner; len(nodes) > 0 { + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -138,7 +156,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -157,17 +175,13 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { // CarUpdateOne is the builder for updating a single Car entity. type CarUpdateOne struct { config - id int - owner map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *CarMutation } // SetOwnerID sets the owner edge to User by id. func (cuo *CarUpdateOne) SetOwnerID(id int) *CarUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[int]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -186,16 +200,37 @@ func (cuo *CarUpdateOne) SetOwner(u *User) *CarUpdateOne { // ClearOwner clears the owner edge to User. func (cuo *CarUpdateOne) ClearOwner() *CarUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // Save executes the query and returns the updated entity. func (cuo *CarUpdateOne) Save(ctx context.Context) (*Car, error) { - if len(cuo.owner) > 1 { - return nil, errors.New("entv2: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Car + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } } - return cuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -226,13 +261,17 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { Table: car.Table, Columns: car.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeInt, Column: car.FieldID, }, }, } - if cuo.clearedOwner { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Car.ID for update") + } + _spec.Node.ID.Value = id + if cuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -248,7 +287,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.owner; len(nodes) > 0 { + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -262,7 +301,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/migrate/entv2/client.go b/entc/integration/migrate/entv2/client.go index 14cf685ac..65c4b18db 100644 --- a/entc/integration/migrate/entv2/client.go +++ b/entc/integration/migrate/entv2/client.go @@ -40,16 +40,19 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Car: NewCarClient(c), - Group: NewGroupClient(c), - Pet: NewPetClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Car = NewCarClient(c.config) + c.Group = NewGroupClient(c.config) + c.Pet = NewPetClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -77,7 +80,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("entv2: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Car: NewCarClient(cfg), @@ -98,15 +101,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Car: NewCarClient(cfg), - Group: NewGroupClient(cfg), - Pet: NewPetClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -114,6 +112,15 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Car.Use(hooks...) + c.Group.Use(hooks...) + c.Pet.Use(hooks...) + c.User.Use(hooks...) +} + // CarClient is a client for the Car schema. type CarClient struct { config @@ -124,14 +131,22 @@ func NewCarClient(c config) *CarClient { return &CarClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `car.Hooks(f(g(h())))`. +func (c *CarClient) Use(hooks ...Hook) { + c.hooks.Car = append(c.hooks.Car, hooks...) +} + // Create returns a create builder for Car. func (c *CarClient) Create() *CarCreate { - return &CarCreate{config: c.config} + mutation := newCarMutation(c.config, OpCreate) + return &CarCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Car. func (c *CarClient) Update() *CarUpdate { - return &CarUpdate{config: c.config} + mutation := newCarMutation(c.config, OpUpdate) + return &CarUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -141,12 +156,15 @@ func (c *CarClient) UpdateOne(ca *Car) *CarUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CarClient) UpdateOneID(id int) *CarUpdateOne { - return &CarUpdateOne{config: c.config, id: id} + mutation := newCarMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CarUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Car. func (c *CarClient) Delete() *CarDelete { - return &CarDelete{config: c.config} + mutation := newCarMutation(c.config, OpDelete) + return &CarDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -156,7 +174,10 @@ func (c *CarClient) DeleteOne(ca *Car) *CarDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CarClient) DeleteOneID(id int) *CarDeleteOne { - return &CarDeleteOne{c.Delete().Where(car.ID(id))} + builder := c.Delete().Where(car.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CarDeleteOne{builder} } // Create returns a query builder for Car. @@ -192,6 +213,11 @@ func (c *CarClient) QueryOwner(ca *Car) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *CarClient) Hooks() []Hook { + return c.hooks.Car +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -202,14 +228,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -219,12 +253,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id int) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -234,7 +271,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id int) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -256,6 +296,11 @@ func (c *GroupClient) GetX(ctx context.Context, id int) *Group { return gr } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -266,14 +311,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -283,12 +336,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id int) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -298,7 +354,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id int) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -320,6 +379,11 @@ func (c *PetClient) GetX(ctx context.Context, id int) *Pet { return pe } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -330,14 +394,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -347,12 +419,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -362,7 +437,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -411,3 +489,8 @@ func (c *UserClient) QueryPets(u *User) *PetQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/migrate/entv2/config.go b/entc/integration/migrate/entv2/config.go index dea08792f..68b9cb673 100644 --- a/entc/integration/migrate/entv2/config.go +++ b/entc/integration/migrate/entv2/config.go @@ -7,6 +7,7 @@ package entv2 import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,16 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Car []ent.Hook + Group []ent.Hook + Pet []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/migrate/entv2/ent.go b/entc/integration/migrate/entv2/ent.go index 7cac2d639..125d6886a 100644 --- a/entc/integration/migrate/entv2/ent.go +++ b/entc/integration/migrate/entv2/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/migrate/entv2/group_create.go b/entc/integration/migrate/entv2/group_create.go index f60451d2d..5c9d49f31 100644 --- a/entc/integration/migrate/entv2/group_create.go +++ b/entc/integration/migrate/entv2/group_create.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/migrate/entv2/group" @@ -17,11 +18,36 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config + mutation *GroupMutation + hooks []Hook } // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - return gc.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. diff --git a/entc/integration/migrate/entv2/group_delete.go b/entc/integration/migrate/entv2/group_delete.go index 7c0030470..7e1ac940d 100644 --- a/entc/integration/migrate/entv2/group_delete.go +++ b/entc/integration/migrate/entv2/group_delete.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/migrate/entv2/group_update.go b/entc/integration/migrate/entv2/group_update.go index bdfb3b0c6..8d97f5e77 100644 --- a/entc/integration/migrate/entv2/group_update.go +++ b/entc/integration/migrate/entv2/group_update.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - return gu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -87,12 +113,36 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id int + hooks []Hook + mutation *GroupMutation } // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - return guo.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -123,12 +173,16 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeInt, Column: group.FieldID, }, }, } + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id gr = &Group{config: guo.config} _spec.Assign = gr.assignValues _spec.ScanValues = gr.scanValues() diff --git a/entc/integration/migrate/entv2/hook/hook.go b/entc/integration/migrate/entv2/hook/hook.go new file mode 100644 index 000000000..ef2aaf22d --- /dev/null +++ b/entc/integration/migrate/entv2/hook/hook.go @@ -0,0 +1,100 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent" +) + +// The CarFunc type is an adapter to allow the use of ordinary +// function as Car mutator. +type CarFunc func(context.Context, *ent.CarMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CarFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CarMutation", m) + } + return f(ctx, mv) +} + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/migrate/entv2/migrate/schema.go b/entc/integration/migrate/entv2/migrate/schema.go index b16fa49b6..2ce35522f 100644 --- a/entc/integration/migrate/entv2/migrate/schema.go +++ b/entc/integration/migrate/entv2/migrate/schema.go @@ -7,8 +7,6 @@ package migrate import ( - "github.com/facebookincubator/ent/entc/integration/migrate/entv2/user" - "github.com/facebookincubator/ent/dialect/sql/schema" "github.com/facebookincubator/ent/schema/field" ) @@ -62,9 +60,9 @@ var ( {Name: "age", Type: field.TypeInt}, {Name: "name", Type: field.TypeString, Size: 2147483647}, {Name: "nickname", Type: field.TypeString}, - {Name: "phone", Type: field.TypeString, Default: user.DefaultPhone}, + {Name: "phone", Type: field.TypeString, Default: "unknown"}, {Name: "buffer", Type: field.TypeBytes, Nullable: true}, - {Name: "title", Type: field.TypeString, Default: user.DefaultTitle}, + {Name: "title", Type: field.TypeString, Default: "SWE"}, {Name: "renamed", Type: field.TypeString, Nullable: true}, {Name: "blob", Type: field.TypeBytes, Nullable: true, Size: 1000}, {Name: "state", Type: field.TypeEnum, Nullable: true, Enums: []string{"logged_in", "logged_out", "online"}}, diff --git a/entc/integration/migrate/entv2/mutation.go b/entc/integration/migrate/entv2/mutation.go new file mode 100644 index 000000000..e80cfa46a --- /dev/null +++ b/entc/integration/migrate/entv2/mutation.go @@ -0,0 +1,1429 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package entv2 + +import ( + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/migrate/entv2/car" + "github.com/facebookincubator/ent/entc/integration/migrate/entv2/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCar = "Car" + TypeGroup = "Group" + TypePet = "Pet" + TypeUser = "User" +) + +// CarMutation represents an operation that mutate the Cars +// nodes in the graph. +type CarMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*CarMutation)(nil) + +// newCarMutation creates new mutation for $n.Name. +func newCarMutation(c config, op Op) *CarMutation { + return &CarMutation{ + config: c, + op: op, + typ: TypeCar, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CarMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CarMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("entv2: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CarMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CarMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CarMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CarMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CarMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CarMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CarMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *CarMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Car). +func (m *CarMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CarMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CarMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CarMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CarMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Car numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CarMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CarMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CarMutation) ClearField(name string) error { + return fmt.Errorf("unknown Car nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CarMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CarMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CarMutation) AddedIDs(name string) []ent.Value { + switch name { + case car.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CarMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CarMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CarMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CarMutation) EdgeCleared(name string) bool { + switch name { + case car.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CarMutation) ClearEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Car unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CarMutation) ResetEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Car edge %s", name) +} + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("entv2: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("entv2: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + nickname *string + phone *string + buffer *[]byte + title *string + new_name *string + blob *[]byte + state *user.State + clearedFields map[string]bool + car map[int]struct{} + removedcar map[int]struct{} + pets *int + clearedpets bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("entv2: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that, this +// operation is accepted only on User creation. +func (m *UserMutation) SetID(id int) { + m.id = &id +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetNickname sets the nickname field. +func (m *UserMutation) SetNickname(s string) { + m.nickname = &s +} + +// Nickname returns the nickname value in the mutation. +func (m *UserMutation) Nickname() (r string, exists bool) { + v := m.nickname + if v == nil { + return + } + return *v, true +} + +// ResetNickname reset all changes of the nickname field. +func (m *UserMutation) ResetNickname() { + m.nickname = nil +} + +// SetPhone sets the phone field. +func (m *UserMutation) SetPhone(s string) { + m.phone = &s +} + +// Phone returns the phone value in the mutation. +func (m *UserMutation) Phone() (r string, exists bool) { + v := m.phone + if v == nil { + return + } + return *v, true +} + +// ResetPhone reset all changes of the phone field. +func (m *UserMutation) ResetPhone() { + m.phone = nil +} + +// SetBuffer sets the buffer field. +func (m *UserMutation) SetBuffer(b []byte) { + m.buffer = &b +} + +// Buffer returns the buffer value in the mutation. +func (m *UserMutation) Buffer() (r []byte, exists bool) { + v := m.buffer + if v == nil { + return + } + return *v, true +} + +// ClearBuffer clears the value of buffer. +func (m *UserMutation) ClearBuffer() { + m.buffer = nil + m.clearedFields[user.FieldBuffer] = true +} + +// BufferCleared returns if the field buffer was cleared in this mutation. +func (m *UserMutation) BufferCleared() bool { + return m.clearedFields[user.FieldBuffer] +} + +// ResetBuffer reset all changes of the buffer field. +func (m *UserMutation) ResetBuffer() { + m.buffer = nil + delete(m.clearedFields, user.FieldBuffer) +} + +// SetTitle sets the title field. +func (m *UserMutation) SetTitle(s string) { + m.title = &s +} + +// Title returns the title value in the mutation. +func (m *UserMutation) Title() (r string, exists bool) { + v := m.title + if v == nil { + return + } + return *v, true +} + +// ResetTitle reset all changes of the title field. +func (m *UserMutation) ResetTitle() { + m.title = nil +} + +// SetNewName sets the new_name field. +func (m *UserMutation) SetNewName(s string) { + m.new_name = &s +} + +// NewName returns the new_name value in the mutation. +func (m *UserMutation) NewName() (r string, exists bool) { + v := m.new_name + if v == nil { + return + } + return *v, true +} + +// ClearNewName clears the value of new_name. +func (m *UserMutation) ClearNewName() { + m.new_name = nil + m.clearedFields[user.FieldNewName] = true +} + +// NewNameCleared returns if the field new_name was cleared in this mutation. +func (m *UserMutation) NewNameCleared() bool { + return m.clearedFields[user.FieldNewName] +} + +// ResetNewName reset all changes of the new_name field. +func (m *UserMutation) ResetNewName() { + m.new_name = nil + delete(m.clearedFields, user.FieldNewName) +} + +// SetBlob sets the blob field. +func (m *UserMutation) SetBlob(b []byte) { + m.blob = &b +} + +// Blob returns the blob value in the mutation. +func (m *UserMutation) Blob() (r []byte, exists bool) { + v := m.blob + if v == nil { + return + } + return *v, true +} + +// ClearBlob clears the value of blob. +func (m *UserMutation) ClearBlob() { + m.blob = nil + m.clearedFields[user.FieldBlob] = true +} + +// BlobCleared returns if the field blob was cleared in this mutation. +func (m *UserMutation) BlobCleared() bool { + return m.clearedFields[user.FieldBlob] +} + +// ResetBlob reset all changes of the blob field. +func (m *UserMutation) ResetBlob() { + m.blob = nil + delete(m.clearedFields, user.FieldBlob) +} + +// SetState sets the state field. +func (m *UserMutation) SetState(u user.State) { + m.state = &u +} + +// State returns the state value in the mutation. +func (m *UserMutation) State() (r user.State, exists bool) { + v := m.state + if v == nil { + return + } + return *v, true +} + +// ClearState clears the value of state. +func (m *UserMutation) ClearState() { + m.state = nil + m.clearedFields[user.FieldState] = true +} + +// StateCleared returns if the field state was cleared in this mutation. +func (m *UserMutation) StateCleared() bool { + return m.clearedFields[user.FieldState] +} + +// ResetState reset all changes of the state field. +func (m *UserMutation) ResetState() { + m.state = nil + delete(m.clearedFields, user.FieldState) +} + +// AddCarIDs adds the car edge to Car by ids. +func (m *UserMutation) AddCarIDs(ids ...int) { + if m.car == nil { + m.car = make(map[int]struct{}) + } + for i := range ids { + m.car[ids[i]] = struct{}{} + } +} + +// RemoveCarIDs removes the car edge to Car by ids. +func (m *UserMutation) RemoveCarIDs(ids ...int) { + if m.removedcar == nil { + m.removedcar = make(map[int]struct{}) + } + for i := range ids { + m.removedcar[ids[i]] = struct{}{} + } +} + +// RemovedCar returns the removed ids of car. +func (m *UserMutation) RemovedCarIDs() (ids []int) { + for id := range m.removedcar { + ids = append(ids, id) + } + return +} + +// CarIDs returns the car ids in the mutation. +func (m *UserMutation) CarIDs() (ids []int) { + for id := range m.car { + ids = append(ids, id) + } + return +} + +// ResetCar reset all changes of the car edge. +func (m *UserMutation) ResetCar() { + m.car = nil + m.removedcar = nil +} + +// SetPetsID sets the pets edge to Pet by id. +func (m *UserMutation) SetPetsID(id int) { + m.pets = &id +} + +// ClearPets clears the pets edge to Pet. +func (m *UserMutation) ClearPets() { + m.clearedpets = true +} + +// PetsCleared returns if the edge pets was cleared. +func (m *UserMutation) PetsCleared() bool { + return m.clearedpets +} + +// PetsID returns the pets id in the mutation. +func (m *UserMutation) PetsID() (id int, exists bool) { + if m.pets != nil { + return *m.pets, true + } + return +} + +// PetsIDs returns the pets ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// PetsID instead. It exists only for internal usage by the builders. +func (m *UserMutation) PetsIDs() (ids []int) { + if id := m.pets; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.clearedpets = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 9) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + if m.nickname != nil { + fields = append(fields, user.FieldNickname) + } + if m.phone != nil { + fields = append(fields, user.FieldPhone) + } + if m.buffer != nil { + fields = append(fields, user.FieldBuffer) + } + if m.title != nil { + fields = append(fields, user.FieldTitle) + } + if m.new_name != nil { + fields = append(fields, user.FieldNewName) + } + if m.blob != nil { + fields = append(fields, user.FieldBlob) + } + if m.state != nil { + fields = append(fields, user.FieldState) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + case user.FieldNickname: + return m.Nickname() + case user.FieldPhone: + return m.Phone() + case user.FieldBuffer: + return m.Buffer() + case user.FieldTitle: + return m.Title() + case user.FieldNewName: + return m.NewName() + case user.FieldBlob: + return m.Blob() + case user.FieldState: + return m.State() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case user.FieldNickname: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNickname(v) + return nil + case user.FieldPhone: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPhone(v) + return nil + case user.FieldBuffer: + v, ok := value.([]byte) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBuffer(v) + return nil + case user.FieldTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTitle(v) + return nil + case user.FieldNewName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNewName(v) + return nil + case user.FieldBlob: + v, ok := value.([]byte) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBlob(v) + return nil + case user.FieldState: + v, ok := value.(user.State) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetState(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[user.FieldBuffer] { + fields = append(fields, user.FieldBuffer) + } + if m.clearedFields[user.FieldNewName] { + fields = append(fields, user.FieldNewName) + } + if m.clearedFields[user.FieldBlob] { + fields = append(fields, user.FieldBlob) + } + if m.clearedFields[user.FieldState] { + fields = append(fields, user.FieldState) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + switch name { + case user.FieldBuffer: + m.ClearBuffer() + return nil + case user.FieldNewName: + m.ClearNewName() + return nil + case user.FieldBlob: + m.ClearBlob() + return nil + case user.FieldState: + m.ClearState() + return nil + } + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + case user.FieldNickname: + m.ResetNickname() + return nil + case user.FieldPhone: + m.ResetPhone() + return nil + case user.FieldBuffer: + m.ResetBuffer() + return nil + case user.FieldTitle: + m.ResetTitle() + return nil + case user.FieldNewName: + m.ResetNewName() + return nil + case user.FieldBlob: + m.ResetBlob() + return nil + case user.FieldState: + m.ResetState() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.car != nil { + edges = append(edges, user.EdgeCar) + } + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeCar: + ids := make([]ent.Value, 0, len(m.car)) + for id := range m.car { + ids = append(ids, id) + } + return ids + case user.EdgePets: + if id := m.pets; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedcar != nil { + edges = append(edges, user.EdgeCar) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeCar: + ids := make([]ent.Value, 0, len(m.removedcar)) + for id := range m.removedcar { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedpets { + edges = append(edges, user.EdgePets) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgePets: + return m.clearedpets + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgePets: + m.ClearPets() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeCar: + m.ResetCar() + return nil + case user.EdgePets: + m.ResetPets() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/migrate/entv2/pet_create.go b/entc/integration/migrate/entv2/pet_create.go index 21aa5e02f..e2e776a04 100644 --- a/entc/integration/migrate/entv2/pet_create.go +++ b/entc/integration/migrate/entv2/pet_create.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/migrate/entv2/pet" @@ -17,11 +18,36 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config + mutation *PetMutation + hooks []Hook } // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - return pc.sqlSave(ctx) + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. diff --git a/entc/integration/migrate/entv2/pet_delete.go b/entc/integration/migrate/entv2/pet_delete.go index d459e936f..9a617495f 100644 --- a/entc/integration/migrate/entv2/pet_delete.go +++ b/entc/integration/migrate/entv2/pet_delete.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/migrate/entv2/pet_update.go b/entc/integration/migrate/entv2/pet_update.go index e507fc527..0860a929d 100644 --- a/entc/integration/migrate/entv2/pet_update.go +++ b/entc/integration/migrate/entv2/pet_update.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - return pu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -87,12 +113,36 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id int + hooks []Hook + mutation *PetMutation } // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - return puo.sqlSave(ctx) + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -123,12 +173,16 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { Table: pet.Table, Columns: pet.Columns, ID: &sqlgraph.FieldSpec{ - Value: puo.id, Type: field.TypeInt, Column: pet.FieldID, }, }, } + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + _spec.Node.ID.Value = id pe = &Pet{config: puo.config} _spec.Assign = pe.assignValues _spec.ScanValues = pe.scanValues() diff --git a/entc/integration/migrate/entv2/privacy/privacy.go b/entc/integration/migrate/entv2/privacy/privacy.go new file mode 100644 index 000000000..ee0c14b03 --- /dev/null +++ b/entc/integration/migrate/entv2/privacy/privacy.go @@ -0,0 +1,243 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/customid/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CarReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CarReadRuleFunc func(context.Context, *ent.Car) error + +// EvalRead calls f(ctx, v). +func (f CarReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Car); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Car", v) +} + +// The CarWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CarWriteRuleFunc func(context.Context, *ent.CarMutation) error + +// EvalWrite calls f(ctx, m). +func (f CarWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CarMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CarMutation", m) +} + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/migrate/entv2/runtime.go b/entc/integration/migrate/entv2/runtime.go new file mode 100644 index 000000000..f41462944 --- /dev/null +++ b/entc/integration/migrate/entv2/runtime.go @@ -0,0 +1,28 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package entv2 + +import ( + "github.com/facebookincubator/ent/entc/integration/migrate/entv2/schema" + + "github.com/facebookincubator/ent/entc/integration/migrate/entv2/user" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + userFields := schema.User{}.Fields() + // userDescPhone is the schema descriptor for phone field. + userDescPhone := userFields[4].Descriptor() + // user.DefaultPhone holds the default value on creation for the phone field. + user.DefaultPhone = userDescPhone.Default.(string) + // userDescTitle is the schema descriptor for title field. + userDescTitle := userFields[6].Descriptor() + // user.DefaultTitle holds the default value on creation for the title field. + user.DefaultTitle = userDescTitle.Default.(string) +} diff --git a/entc/integration/migrate/entv2/runtime/runtime.go b/entc/integration/migrate/entv2/runtime/runtime.go new file mode 100644 index 000000000..fb94ac374 --- /dev/null +++ b/entc/integration/migrate/entv2/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/migrate/entv2/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/migrate/entv2/tx.go b/entc/integration/migrate/entv2/tx.go index b568beb8b..966c4f6ef 100644 --- a/entc/integration/migrate/entv2/tx.go +++ b/entc/integration/migrate/entv2/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/migrate/entv2/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -38,14 +37,16 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Car: NewCarClient(tx.config), - Group: NewGroupClient(tx.config), - Pet: NewPetClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Car = NewCarClient(tx.config) + tx.Group = NewGroupClient(tx.config) + tx.Pet = NewPetClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/migrate/entv2/user/user.go b/entc/integration/migrate/entv2/user/user.go index 3850d2310..d79d81d43 100644 --- a/entc/integration/migrate/entv2/user/user.go +++ b/entc/integration/migrate/entv2/user/user.go @@ -8,33 +8,27 @@ package user import ( "fmt" - - "github.com/facebookincubator/ent/entc/integration/migrate/entv2/schema" ) const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "oid" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. - FieldName = "name" - // FieldNickname holds the string denoting the nickname vertex property in the database. - FieldNickname = "nickname" - // FieldPhone holds the string denoting the phone vertex property in the database. - FieldPhone = "phone" - // FieldBuffer holds the string denoting the buffer vertex property in the database. - FieldBuffer = "buffer" - // FieldTitle holds the string denoting the title vertex property in the database. - FieldTitle = "title" - // FieldNewName holds the string denoting the new_name vertex property in the database. - FieldNewName = "renamed" - // FieldBlob holds the string denoting the blob vertex property in the database. - FieldBlob = "blob" - // FieldState holds the string denoting the state vertex property in the database. - FieldState = "state" + FieldID = "oid" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldNickname holds the string denoting the nickname vertex property in the database. + FieldNickname = "nickname" // FieldPhone holds the string denoting the phone vertex property in the database. + FieldPhone = "phone" // FieldBuffer holds the string denoting the buffer vertex property in the database. + FieldBuffer = "buffer" // FieldTitle holds the string denoting the title vertex property in the database. + FieldTitle = "title" // FieldNewName holds the string denoting the new_name vertex property in the database. + FieldNewName = "renamed" // FieldBlob holds the string denoting the blob vertex property in the database. + FieldBlob = "blob" // FieldState holds the string denoting the state vertex property in the database. + FieldState = "state" + + // EdgeCar holds the string denoting the car edge name in mutations. + EdgeCar = "car" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" // Table holds the table name of the user in the database. Table = "users" @@ -74,17 +68,10 @@ var ForeignKeys = []string{ } var ( - fields = schema.User{}.Fields() - - // descPhone is the schema descriptor for phone field. - descPhone = fields[4].Descriptor() // DefaultPhone holds the default value on creation for the phone field. - DefaultPhone = descPhone.Default.(string) - - // descTitle is the schema descriptor for title field. - descTitle = fields[6].Descriptor() + DefaultPhone string // DefaultTitle holds the default value on creation for the title field. - DefaultTitle = descTitle.Default.(string) + DefaultTitle string ) // State defines the type for the state enum field. diff --git a/entc/integration/migrate/entv2/user_create.go b/entc/integration/migrate/entv2/user_create.go index 983174437..dfd598d9e 100644 --- a/entc/integration/migrate/entv2/user_create.go +++ b/entc/integration/migrate/entv2/user_create.go @@ -21,41 +21,31 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - id *int - age *int - name *string - nickname *string - phone *string - buffer *[]byte - title *string - new_name *string - blob *[]byte - state *user.State - car map[int]struct{} - pets map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetNickname sets the nickname field. func (uc *UserCreate) SetNickname(s string) *UserCreate { - uc.nickname = &s + uc.mutation.SetNickname(s) return uc } // SetPhone sets the phone field. func (uc *UserCreate) SetPhone(s string) *UserCreate { - uc.phone = &s + uc.mutation.SetPhone(s) return uc } @@ -69,13 +59,13 @@ func (uc *UserCreate) SetNillablePhone(s *string) *UserCreate { // SetBuffer sets the buffer field. func (uc *UserCreate) SetBuffer(b []byte) *UserCreate { - uc.buffer = &b + uc.mutation.SetBuffer(b) return uc } // SetTitle sets the title field. func (uc *UserCreate) SetTitle(s string) *UserCreate { - uc.title = &s + uc.mutation.SetTitle(s) return uc } @@ -89,7 +79,7 @@ func (uc *UserCreate) SetNillableTitle(s *string) *UserCreate { // SetNewName sets the new_name field. func (uc *UserCreate) SetNewName(s string) *UserCreate { - uc.new_name = &s + uc.mutation.SetNewName(s) return uc } @@ -103,13 +93,13 @@ func (uc *UserCreate) SetNillableNewName(s *string) *UserCreate { // SetBlob sets the blob field. func (uc *UserCreate) SetBlob(b []byte) *UserCreate { - uc.blob = &b + uc.mutation.SetBlob(b) return uc } // SetState sets the state field. func (uc *UserCreate) SetState(u user.State) *UserCreate { - uc.state = &u + uc.mutation.SetState(u) return uc } @@ -123,18 +113,13 @@ func (uc *UserCreate) SetNillableState(u *user.State) *UserCreate { // SetID sets the id field. func (uc *UserCreate) SetID(i int) *UserCreate { - uc.id = &i + uc.mutation.SetID(i) return uc } // AddCarIDs adds the car edge to Car by ids. func (uc *UserCreate) AddCarIDs(ids ...int) *UserCreate { - if uc.car == nil { - uc.car = make(map[int]struct{}) - } - for i := range ids { - uc.car[ids[i]] = struct{}{} - } + uc.mutation.AddCarIDs(ids...) return uc } @@ -149,10 +134,7 @@ func (uc *UserCreate) AddCar(c ...*Car) *UserCreate { // SetPetsID sets the pets edge to Pet by id. func (uc *UserCreate) SetPetsID(id int) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[int]struct{}) - } - uc.pets[id] = struct{}{} + uc.mutation.SetPetsID(id) return uc } @@ -171,32 +153,52 @@ func (uc *UserCreate) SetPets(p *Pet) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("entv2: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("entv2: missing required field \"name\"") } - if uc.nickname == nil { + if _, ok := uc.mutation.Nickname(); !ok { return nil, errors.New("entv2: missing required field \"nickname\"") } - if uc.phone == nil { + if _, ok := uc.mutation.Phone(); !ok { v := user.DefaultPhone - uc.phone = &v + uc.mutation.SetPhone(v) } - if uc.title == nil { + if _, ok := uc.mutation.Title(); !ok { v := user.DefaultTitle - uc.title = &v + uc.mutation.SetTitle(v) } - if uc.state != nil { - if err := user.StateValidator(*uc.state); err != nil { + if v, ok := uc.mutation.State(); ok { + if err := user.StateValidator(v); err != nil { return nil, fmt.Errorf("entv2: validator failed for field \"state\": %v", err) } } - if len(uc.pets) > 1 { - return nil, errors.New("entv2: multiple assignments on a unique edge \"pets\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -219,83 +221,83 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.id; value != nil { - u.ID = *value - _spec.ID.Value = *value + if id, ok := uc.mutation.ID(); ok { + u.ID = id + _spec.ID.Value = id } - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if value := uc.nickname; value != nil { + if value, ok := uc.mutation.Nickname(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) - u.Nickname = *value + u.Nickname = value } - if value := uc.phone; value != nil { + if value, ok := uc.mutation.Phone(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPhone, }) - u.Phone = *value + u.Phone = value } - if value := uc.buffer; value != nil { + if value, ok := uc.mutation.Buffer(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBuffer, }) - u.Buffer = *value + u.Buffer = value } - if value := uc.title; value != nil { + if value, ok := uc.mutation.Title(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldTitle, }) - u.Title = *value + u.Title = value } - if value := uc.new_name; value != nil { + if value, ok := uc.mutation.NewName(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNewName, }) - u.NewName = *value + u.NewName = value } - if value := uc.blob; value != nil { + if value, ok := uc.mutation.Blob(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBlob, }) - u.Blob = *value + u.Blob = value } - if value := uc.state; value != nil { + if value, ok := uc.mutation.State(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldState, }) - u.State = *value + u.State = value } - if nodes := uc.car; len(nodes) > 0 { + if nodes := uc.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -309,12 +311,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.pets; len(nodes) > 0 { + if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -328,7 +330,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/migrate/entv2/user_delete.go b/entc/integration/migrate/entv2/user_delete.go index a0864adc6..5f44690c4 100644 --- a/entc/integration/migrate/entv2/user_delete.go +++ b/entc/integration/migrate/entv2/user_delete.go @@ -8,6 +8,7 @@ package entv2 import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/migrate/entv2/user_update.go b/entc/integration/migrate/entv2/user_update.go index b0db8dd29..4d5488906 100644 --- a/entc/integration/migrate/entv2/user_update.go +++ b/entc/integration/migrate/entv2/user_update.go @@ -8,7 +8,6 @@ package entv2 import ( "context" - "errors" "fmt" "github.com/facebookincubator/ent/dialect/sql" @@ -23,25 +22,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - nickname *string - phone *string - buffer *[]byte - clearbuffer bool - title *string - new_name *string - clearnew_name bool - blob *[]byte - clearblob bool - state *user.State - clearstate bool - car map[int]struct{} - pets map[int]struct{} - removedCar map[int]struct{} - clearedPets bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -52,36 +35,32 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetNickname sets the nickname field. func (uu *UserUpdate) SetNickname(s string) *UserUpdate { - uu.nickname = &s + uu.mutation.SetNickname(s) return uu } // SetPhone sets the phone field. func (uu *UserUpdate) SetPhone(s string) *UserUpdate { - uu.phone = &s + uu.mutation.SetPhone(s) return uu } @@ -95,20 +74,19 @@ func (uu *UserUpdate) SetNillablePhone(s *string) *UserUpdate { // SetBuffer sets the buffer field. func (uu *UserUpdate) SetBuffer(b []byte) *UserUpdate { - uu.buffer = &b + uu.mutation.SetBuffer(b) return uu } // ClearBuffer clears the value of buffer. func (uu *UserUpdate) ClearBuffer() *UserUpdate { - uu.buffer = nil - uu.clearbuffer = true + uu.mutation.ClearBuffer() return uu } // SetTitle sets the title field. func (uu *UserUpdate) SetTitle(s string) *UserUpdate { - uu.title = &s + uu.mutation.SetTitle(s) return uu } @@ -122,7 +100,7 @@ func (uu *UserUpdate) SetNillableTitle(s *string) *UserUpdate { // SetNewName sets the new_name field. func (uu *UserUpdate) SetNewName(s string) *UserUpdate { - uu.new_name = &s + uu.mutation.SetNewName(s) return uu } @@ -136,27 +114,25 @@ func (uu *UserUpdate) SetNillableNewName(s *string) *UserUpdate { // ClearNewName clears the value of new_name. func (uu *UserUpdate) ClearNewName() *UserUpdate { - uu.new_name = nil - uu.clearnew_name = true + uu.mutation.ClearNewName() return uu } // SetBlob sets the blob field. func (uu *UserUpdate) SetBlob(b []byte) *UserUpdate { - uu.blob = &b + uu.mutation.SetBlob(b) return uu } // ClearBlob clears the value of blob. func (uu *UserUpdate) ClearBlob() *UserUpdate { - uu.blob = nil - uu.clearblob = true + uu.mutation.ClearBlob() return uu } // SetState sets the state field. func (uu *UserUpdate) SetState(u user.State) *UserUpdate { - uu.state = &u + uu.mutation.SetState(u) return uu } @@ -170,19 +146,13 @@ func (uu *UserUpdate) SetNillableState(u *user.State) *UserUpdate { // ClearState clears the value of state. func (uu *UserUpdate) ClearState() *UserUpdate { - uu.state = nil - uu.clearstate = true + uu.mutation.ClearState() return uu } // AddCarIDs adds the car edge to Car by ids. func (uu *UserUpdate) AddCarIDs(ids ...int) *UserUpdate { - if uu.car == nil { - uu.car = make(map[int]struct{}) - } - for i := range ids { - uu.car[ids[i]] = struct{}{} - } + uu.mutation.AddCarIDs(ids...) return uu } @@ -197,10 +167,7 @@ func (uu *UserUpdate) AddCar(c ...*Car) *UserUpdate { // SetPetsID sets the pets edge to Pet by id. func (uu *UserUpdate) SetPetsID(id int) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[int]struct{}) - } - uu.pets[id] = struct{}{} + uu.mutation.SetPetsID(id) return uu } @@ -219,12 +186,7 @@ func (uu *UserUpdate) SetPets(p *Pet) *UserUpdate { // RemoveCarIDs removes the car edge to Car by ids. func (uu *UserUpdate) RemoveCarIDs(ids ...int) *UserUpdate { - if uu.removedCar == nil { - uu.removedCar = make(map[int]struct{}) - } - for i := range ids { - uu.removedCar[ids[i]] = struct{}{} - } + uu.mutation.RemoveCarIDs(ids...) return uu } @@ -239,21 +201,42 @@ func (uu *UserUpdate) RemoveCar(c ...*Car) *UserUpdate { // ClearPets clears the pets edge to Pet. func (uu *UserUpdate) ClearPets() *UserUpdate { - uu.clearedPets = true + uu.mutation.ClearPets() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if uu.state != nil { - if err := user.StateValidator(*uu.state); err != nil { + if v, ok := uu.mutation.State(); ok { + if err := user.StateValidator(v); err != nil { return 0, fmt.Errorf("entv2: validator failed for field \"state\": %v", err) } } - if len(uu.pets) > 1 { - return 0, errors.New("entv2: multiple assignments on a unique edge \"pets\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -296,101 +279,101 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if value := uu.nickname; value != nil { + if value, ok := uu.mutation.Nickname(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) } - if value := uu.phone; value != nil { + if value, ok := uu.mutation.Phone(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPhone, }) } - if value := uu.buffer; value != nil { + if value, ok := uu.mutation.Buffer(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBuffer, }) } - if uu.clearbuffer { + if uu.mutation.BufferCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeBytes, Column: user.FieldBuffer, }) } - if value := uu.title; value != nil { + if value, ok := uu.mutation.Title(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldTitle, }) } - if value := uu.new_name; value != nil { + if value, ok := uu.mutation.NewName(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNewName, }) } - if uu.clearnew_name { + if uu.mutation.NewNameCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldNewName, }) } - if value := uu.blob; value != nil { + if value, ok := uu.mutation.Blob(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBlob, }) } - if uu.clearblob { + if uu.mutation.BlobCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeBytes, Column: user.FieldBlob, }) } - if value := uu.state; value != nil { + if value, ok := uu.mutation.State(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldState, }) } - if uu.clearstate { + if uu.mutation.StateCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeEnum, Column: user.FieldState, }) } - if nodes := uu.removedCar; len(nodes) > 0 { + if nodes := uu.mutation.RemovedCarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -404,12 +387,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.car; len(nodes) > 0 { + if nodes := uu.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -423,12 +406,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uu.clearedPets { + if uu.mutation.PetsCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -444,7 +427,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.pets; len(nodes) > 0 { + if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -458,7 +441,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -477,59 +460,38 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - nickname *string - phone *string - buffer *[]byte - clearbuffer bool - title *string - new_name *string - clearnew_name bool - blob *[]byte - clearblob bool - state *user.State - clearstate bool - car map[int]struct{} - pets map[int]struct{} - removedCar map[int]struct{} - clearedPets bool + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetNickname sets the nickname field. func (uuo *UserUpdateOne) SetNickname(s string) *UserUpdateOne { - uuo.nickname = &s + uuo.mutation.SetNickname(s) return uuo } // SetPhone sets the phone field. func (uuo *UserUpdateOne) SetPhone(s string) *UserUpdateOne { - uuo.phone = &s + uuo.mutation.SetPhone(s) return uuo } @@ -543,20 +505,19 @@ func (uuo *UserUpdateOne) SetNillablePhone(s *string) *UserUpdateOne { // SetBuffer sets the buffer field. func (uuo *UserUpdateOne) SetBuffer(b []byte) *UserUpdateOne { - uuo.buffer = &b + uuo.mutation.SetBuffer(b) return uuo } // ClearBuffer clears the value of buffer. func (uuo *UserUpdateOne) ClearBuffer() *UserUpdateOne { - uuo.buffer = nil - uuo.clearbuffer = true + uuo.mutation.ClearBuffer() return uuo } // SetTitle sets the title field. func (uuo *UserUpdateOne) SetTitle(s string) *UserUpdateOne { - uuo.title = &s + uuo.mutation.SetTitle(s) return uuo } @@ -570,7 +531,7 @@ func (uuo *UserUpdateOne) SetNillableTitle(s *string) *UserUpdateOne { // SetNewName sets the new_name field. func (uuo *UserUpdateOne) SetNewName(s string) *UserUpdateOne { - uuo.new_name = &s + uuo.mutation.SetNewName(s) return uuo } @@ -584,27 +545,25 @@ func (uuo *UserUpdateOne) SetNillableNewName(s *string) *UserUpdateOne { // ClearNewName clears the value of new_name. func (uuo *UserUpdateOne) ClearNewName() *UserUpdateOne { - uuo.new_name = nil - uuo.clearnew_name = true + uuo.mutation.ClearNewName() return uuo } // SetBlob sets the blob field. func (uuo *UserUpdateOne) SetBlob(b []byte) *UserUpdateOne { - uuo.blob = &b + uuo.mutation.SetBlob(b) return uuo } // ClearBlob clears the value of blob. func (uuo *UserUpdateOne) ClearBlob() *UserUpdateOne { - uuo.blob = nil - uuo.clearblob = true + uuo.mutation.ClearBlob() return uuo } // SetState sets the state field. func (uuo *UserUpdateOne) SetState(u user.State) *UserUpdateOne { - uuo.state = &u + uuo.mutation.SetState(u) return uuo } @@ -618,19 +577,13 @@ func (uuo *UserUpdateOne) SetNillableState(u *user.State) *UserUpdateOne { // ClearState clears the value of state. func (uuo *UserUpdateOne) ClearState() *UserUpdateOne { - uuo.state = nil - uuo.clearstate = true + uuo.mutation.ClearState() return uuo } // AddCarIDs adds the car edge to Car by ids. func (uuo *UserUpdateOne) AddCarIDs(ids ...int) *UserUpdateOne { - if uuo.car == nil { - uuo.car = make(map[int]struct{}) - } - for i := range ids { - uuo.car[ids[i]] = struct{}{} - } + uuo.mutation.AddCarIDs(ids...) return uuo } @@ -645,10 +598,7 @@ func (uuo *UserUpdateOne) AddCar(c ...*Car) *UserUpdateOne { // SetPetsID sets the pets edge to Pet by id. func (uuo *UserUpdateOne) SetPetsID(id int) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[int]struct{}) - } - uuo.pets[id] = struct{}{} + uuo.mutation.SetPetsID(id) return uuo } @@ -667,12 +617,7 @@ func (uuo *UserUpdateOne) SetPets(p *Pet) *UserUpdateOne { // RemoveCarIDs removes the car edge to Car by ids. func (uuo *UserUpdateOne) RemoveCarIDs(ids ...int) *UserUpdateOne { - if uuo.removedCar == nil { - uuo.removedCar = make(map[int]struct{}) - } - for i := range ids { - uuo.removedCar[ids[i]] = struct{}{} - } + uuo.mutation.RemoveCarIDs(ids...) return uuo } @@ -687,21 +632,42 @@ func (uuo *UserUpdateOne) RemoveCar(c ...*Car) *UserUpdateOne { // ClearPets clears the pets edge to Pet. func (uuo *UserUpdateOne) ClearPets() *UserUpdateOne { - uuo.clearedPets = true + uuo.mutation.ClearPets() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if uuo.state != nil { - if err := user.StateValidator(*uuo.state); err != nil { + if v, ok := uuo.mutation.State(); ok { + if err := user.StateValidator(v); err != nil { return nil, fmt.Errorf("entv2: validator failed for field \"state\": %v", err) } } - if len(uuo.pets) > 1 { - return nil, errors.New("entv2: multiple assignments on a unique edge \"pets\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -732,107 +698,111 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if value := uuo.nickname; value != nil { + if value, ok := uuo.mutation.Nickname(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNickname, }) } - if value := uuo.phone; value != nil { + if value, ok := uuo.mutation.Phone(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldPhone, }) } - if value := uuo.buffer; value != nil { + if value, ok := uuo.mutation.Buffer(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBuffer, }) } - if uuo.clearbuffer { + if uuo.mutation.BufferCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeBytes, Column: user.FieldBuffer, }) } - if value := uuo.title; value != nil { + if value, ok := uuo.mutation.Title(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldTitle, }) } - if value := uuo.new_name; value != nil { + if value, ok := uuo.mutation.NewName(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldNewName, }) } - if uuo.clearnew_name { + if uuo.mutation.NewNameCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeString, Column: user.FieldNewName, }) } - if value := uuo.blob; value != nil { + if value, ok := uuo.mutation.Blob(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBytes, - Value: *value, + Value: value, Column: user.FieldBlob, }) } - if uuo.clearblob { + if uuo.mutation.BlobCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeBytes, Column: user.FieldBlob, }) } - if value := uuo.state; value != nil { + if value, ok := uuo.mutation.State(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeEnum, - Value: *value, + Value: value, Column: user.FieldState, }) } - if uuo.clearstate { + if uuo.mutation.StateCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeEnum, Column: user.FieldState, }) } - if nodes := uuo.removedCar; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedCarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -846,12 +816,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.car; len(nodes) > 0 { + if nodes := uuo.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -865,12 +835,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if uuo.clearedPets { + if uuo.mutation.PetsCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -886,7 +856,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.pets; len(nodes) > 0 { + if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -900,7 +870,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/privacy/ent/client.go b/entc/integration/privacy/ent/client.go new file mode 100644 index 000000000..ac01cab1f --- /dev/null +++ b/entc/integration/privacy/ent/client.go @@ -0,0 +1,202 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "log" + + "github.com/facebookincubator/ent/entc/integration/privacy/ent/migrate" + + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" +) + +// Client is the client that holds all ent builders. +type Client struct { + config + // Schema is the client for creating, migrating and dropping schema. + Schema *migrate.Schema + // Planet is the client for interacting with the Planet builders. + Planet *PlanetClient +} + +// NewClient creates a new client configured with the given options. +func NewClient(opts ...Option) *Client { + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Planet = NewPlanetClient(c.config) +} + +// Open opens a connection to the database specified by the driver name and a +// driver-specific data source name, and returns a new client attached to it. +// Optional parameters can be added for configuring the client. +func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { + switch driverName { + case dialect.MySQL, dialect.Postgres, dialect.SQLite: + drv, err := sql.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + return NewClient(append(options, Driver(drv))...), nil + default: + return nil, fmt.Errorf("unsupported driver: %q", driverName) + } +} + +// Tx returns a new transactional client. +func (c *Client) Tx(ctx context.Context) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") + } + tx, err := newTx(ctx, c.driver) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %v", err) + } + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} + return &Tx{ + config: cfg, + Planet: NewPlanetClient(cfg), + }, nil +} + +// Debug returns a new debug-client. It's used to get verbose logging on specific operations. +// +// client.Debug(). +// Planet. +// Query(). +// Count(ctx) +// +func (c *Client) Debug() *Client { + if c.debug { + return c + } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client +} + +// Close closes the database connection and prevents new queries from starting. +func (c *Client) Close() error { + return c.driver.Close() +} + +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Planet.Use(hooks...) +} + +// PlanetClient is a client for the Planet schema. +type PlanetClient struct { + config +} + +// NewPlanetClient returns a client for the Planet from the given config. +func NewPlanetClient(c config) *PlanetClient { + return &PlanetClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `planet.Hooks(f(g(h())))`. +func (c *PlanetClient) Use(hooks ...Hook) { + c.hooks.Planet = append(c.hooks.Planet, hooks...) +} + +// Create returns a create builder for Planet. +func (c *PlanetClient) Create() *PlanetCreate { + mutation := newPlanetMutation(c.config, OpCreate) + return &PlanetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Update returns an update builder for Planet. +func (c *PlanetClient) Update() *PlanetUpdate { + mutation := newPlanetMutation(c.config, OpUpdate) + return &PlanetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *PlanetClient) UpdateOne(pl *Planet) *PlanetUpdateOne { + return c.UpdateOneID(pl.ID) +} + +// UpdateOneID returns an update builder for the given id. +func (c *PlanetClient) UpdateOneID(id int) *PlanetUpdateOne { + mutation := newPlanetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PlanetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Planet. +func (c *PlanetClient) Delete() *PlanetDelete { + mutation := newPlanetMutation(c.config, OpDelete) + return &PlanetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a delete builder for the given entity. +func (c *PlanetClient) DeleteOne(pl *Planet) *PlanetDeleteOne { + return c.DeleteOneID(pl.ID) +} + +// DeleteOneID returns a delete builder for the given id. +func (c *PlanetClient) DeleteOneID(id int) *PlanetDeleteOne { + builder := c.Delete().Where(planet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PlanetDeleteOne{builder} +} + +// Create returns a query builder for Planet. +func (c *PlanetClient) Query() *PlanetQuery { + return &PlanetQuery{config: c.config} +} + +// Get returns a Planet entity by its id. +func (c *PlanetClient) Get(ctx context.Context, id int) (*Planet, error) { + return c.Query().Where(planet.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *PlanetClient) GetX(ctx context.Context, id int) *Planet { + pl, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return pl +} + +// QueryNeighbors queries the neighbors edge of a Planet. +func (c *PlanetClient) QueryNeighbors(pl *Planet) *PlanetQuery { + query := &PlanetQuery{config: c.config} + id := pl.ID + step := sqlgraph.NewStep( + sqlgraph.From(planet.Table, planet.FieldID, id), + sqlgraph.To(planet.Table, planet.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, planet.NeighborsTable, planet.NeighborsPrimaryKey...), + ) + query.sql = sqlgraph.Neighbors(pl.driver.Dialect(), step) + + return query +} + +// Hooks returns the client hooks. +func (c *PlanetClient) Hooks() []Hook { + hooks := c.hooks.Planet + return append(hooks[:len(hooks):len(hooks)], planet.Hooks[:]...) +} diff --git a/entc/integration/privacy/ent/config.go b/entc/integration/privacy/ent/config.go new file mode 100644 index 000000000..6608d2c6c --- /dev/null +++ b/entc/integration/privacy/ent/config.go @@ -0,0 +1,63 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/dialect" +) + +// Option function to configure the client. +type Option func(*config) + +// Config is the configuration for the client and its builder. +type config struct { + // driver used for executing database requests. + driver dialect.Driver + // debug enable a debug logging. + debug bool + // log used for logging on debug mode. + log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Planet []ent.Hook +} + +// Options applies the options on the config object. +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } + if c.debug { + c.driver = dialect.Debug(c.driver, c.log) + } +} + +// Debug enables debug logging on the ent.Driver. +func Debug() Option { + return func(c *config) { + c.debug = true + } +} + +// Log sets the logging function for debug mode. +func Log(fn func(...interface{})) Option { + return func(c *config) { + c.log = fn + } +} + +// Driver configures the client driver. +func Driver(driver dialect.Driver) Option { + return func(c *config) { + c.driver = driver + } +} diff --git a/entc/integration/privacy/ent/context.go b/entc/integration/privacy/ent/context.go new file mode 100644 index 000000000..57ecd33b3 --- /dev/null +++ b/entc/integration/privacy/ent/context.go @@ -0,0 +1,24 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" +) + +type contextKey struct{} + +// FromContext returns the Client stored in a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Client { + c, _ := ctx.Value(contextKey{}).(*Client) + return c +} + +// NewContext returns a new context with the given Client attached. +func NewContext(parent context.Context, c *Client) context.Context { + return context.WithValue(parent, contextKey{}, c) +} diff --git a/entc/integration/privacy/ent/ent.go b/entc/integration/privacy/ent/ent.go new file mode 100644 index 000000000..468ee7ba7 --- /dev/null +++ b/entc/integration/privacy/ent/ent.go @@ -0,0 +1,265 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "strings" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "golang.org/x/xerrors" +) + +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + +// Order applies an ordering on either graph traversal or sql selector. +type Order func(*sql.Selector) + +// Asc applies the given fields in ASC order. +func Asc(fields ...string) Order { + return func(s *sql.Selector) { + for _, f := range fields { + s.OrderBy(sql.Asc(f)) + } + } +} + +// Desc applies the given fields in DESC order. +func Desc(fields ...string) Order { + return func(s *sql.Selector) { + for _, f := range fields { + s.OrderBy(sql.Desc(f)) + } + } +} + +// Aggregate applies an aggregation step on the group-by traversal/selector. +type Aggregate func(*sql.Selector) string + +// As is a pseudo aggregation function for renaming another other functions with custom names. For example: +// +// GroupBy(field1, field2). +// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). +// Scan(ctx, &v) +// +func As(fn Aggregate, end string) Aggregate { + return func(s *sql.Selector) string { + return sql.As(fn(s), end) + } +} + +// Count applies the "count" aggregation function on each group. +func Count() Aggregate { + return func(s *sql.Selector) string { + return sql.Count("*") + } +} + +// Max applies the "max" aggregation function on the given field of each group. +func Max(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Max(s.C(field)) + } +} + +// Mean applies the "mean" aggregation function on the given field of each group. +func Mean(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Avg(s.C(field)) + } +} + +// Min applies the "min" aggregation function on the given field of each group. +func Min(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Min(s.C(field)) + } +} + +// Sum applies the "sum" aggregation function on the given field of each group. +func Sum(field string) Aggregate { + return func(s *sql.Selector) string { + return sql.Sum(s.C(field)) + } +} + +// NotFoundError returns when trying to fetch a specific entity and it was not found in the database. +type NotFoundError struct { + label string +} + +// Error implements the error interface. +func (e *NotFoundError) Error() string { + return "ent: " + e.label + " not found" +} + +// IsNotFound returns a boolean indicating whether the error is a not found error. +func IsNotFound(err error) bool { + if err == nil { + return false + } + var e *NotFoundError + return xerrors.As(err, &e) +} + +// MaskNotFound masks nor found error. +func MaskNotFound(err error) error { + if IsNotFound(err) { + return nil + } + return err +} + +// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database. +type NotSingularError struct { + label string +} + +// Error implements the error interface. +func (e *NotSingularError) Error() string { + return "ent: " + e.label + " not singular" +} + +// IsNotSingular returns a boolean indicating whether the error is a not singular error. +func IsNotSingular(err error) bool { + if err == nil { + return false + } + var e *NotSingularError + return xerrors.As(err, &e) +} + +// NotLoadedError returns when trying to get a node that was not loaded by the query. +type NotLoadedError struct { + edge string +} + +// Error implements the error interface. +func (e *NotLoadedError) Error() string { + return "ent: " + e.edge + " edge was not loaded" +} + +// IsNotLoaded returns a boolean indicating whether the error is a not loaded error. +func IsNotLoaded(err error) bool { + if err == nil { + return false + } + var e *NotLoadedError + return xerrors.As(err, &e) +} + +// ConstraintError returns when trying to create/update one or more entities and +// one or more of their constraints failed. For example, violation of edge or +// field uniqueness. +type ConstraintError struct { + msg string + wrap error +} + +// Error implements the error interface. +func (e ConstraintError) Error() string { + return "ent: constraint failed: " + e.msg +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ConstraintError) Unwrap() error { + return e.wrap +} + +// IsConstraintError returns a boolean indicating whether the error is a constraint failure. +func IsConstraintError(err error) bool { + if err == nil { + return false + } + var e *ConstraintError + return xerrors.As(err, &e) +} + +func isSQLConstraintError(err error) (*ConstraintError, bool) { + var ( + msg = err.Error() + // error format per dialect. + errors = [...]string{ + "Error 1062", // MySQL 1062 error (ER_DUP_ENTRY). + "UNIQUE constraint failed", // SQLite. + "duplicate key value violates unique constraint", // PostgreSQL. + } + ) + if _, ok := err.(*sqlgraph.ConstraintError); ok { + return &ConstraintError{msg, err}, true + } + for i := range errors { + if strings.Contains(msg, errors[i]) { + return &ConstraintError{msg, err}, true + } + } + return nil, false +} + +// rollback calls to tx.Rollback and wraps the given error with the rollback error if occurred. +func rollback(tx dialect.Tx, err error) error { + if rerr := tx.Rollback(); rerr != nil { + err = fmt.Errorf("%s: %v", err.Error(), rerr) + } + if err, ok := isSQLConstraintError(err); ok { + return err + } + return err +} + +// insertLastID invokes the insert query on the transaction and returns the LastInsertID. +func insertLastID(ctx context.Context, tx dialect.Tx, insert *sql.InsertBuilder) (int64, error) { + query, args := insert.Query() + // PostgreSQL does not support the LastInsertId() method of sql.Result + // on Exec, and should be extracted manually using the `RETURNING` clause. + if insert.Dialect() == dialect.Postgres { + rows := &sql.Rows{} + if err := tx.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, fmt.Errorf("no rows found for query: %v", query) + } + var id int64 + if err := rows.Scan(&id); err != nil { + return 0, err + } + return id, nil + } + // MySQL, SQLite, etc. + var res sql.Result + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, err + } + id, err := res.LastInsertId() + if err != nil { + return 0, err + } + return id, nil +} + +// keys returns the keys/ids from the edge map. +func keys(m map[int]struct{}) []int { + s := make([]int, 0, len(m)) + for id := range m { + s = append(s, id) + } + return s +} diff --git a/entc/integration/privacy/ent/generate.go b/entc/integration/privacy/ent/generate.go new file mode 100644 index 000000000..26146318a --- /dev/null +++ b/entc/integration/privacy/ent/generate.go @@ -0,0 +1,7 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package ent + +//go:generate go run github.com/facebookincubator/ent/cmd/entc generate --header "// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.\n// This source code is licensed under the Apache 2.0 license found\n// in the LICENSE file in the root directory of this source tree.\n\n// Code generated by entc, DO NOT EDIT." ./schema diff --git a/entc/integration/privacy/ent/hook/hook.go b/entc/integration/privacy/ent/hook/hook.go new file mode 100644 index 000000000..40669371b --- /dev/null +++ b/entc/integration/privacy/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/privacy/ent" +) + +// The PlanetFunc type is an adapter to allow the use of ordinary +// function as Planet mutator. +type PlanetFunc func(context.Context, *ent.PlanetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PlanetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PlanetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PlanetMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/privacy/ent/migrate/migrate.go b/entc/integration/privacy/ent/migrate/migrate.go new file mode 100644 index 000000000..1c1cd7a5c --- /dev/null +++ b/entc/integration/privacy/ent/migrate/migrate.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package migrate + +import ( + "context" + "fmt" + "io" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql/schema" +) + +var ( + // WithGlobalUniqueID sets the universal ids options to the migration. + // If this option is enabled, ent migration will allocate a 1<<32 range + // for the ids of each entity (table). + // Note that this option cannot be applied on tables that already exist. + WithGlobalUniqueID = schema.WithGlobalUniqueID + // WithDropColumn sets the drop column option to the migration. + // If this option is enabled, ent migration will drop old columns + // that were used for both fields and edges. This defaults to false. + WithDropColumn = schema.WithDropColumn + // WithDropIndex sets the drop index option to the migration. + // If this option is enabled, ent migration will drop old indexes + // that were defined in the schema. This defaults to false. + // Note that unique constraints are defined using `UNIQUE INDEX`, + // and therefore, it's recommended to enable this option to get more + // flexibility in the schema changes. + WithDropIndex = schema.WithDropIndex + // WithFixture sets the foreign-key renaming option to the migration when upgrading + // ent from v0.1.0 (issue-#285). Defaults to true. + WithFixture = schema.WithFixture +) + +// Schema is the API for creating, migrating and dropping a schema. +type Schema struct { + drv dialect.Driver + universalID bool +} + +// NewSchema creates a new schema client. +func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } + +// Create creates all schema resources. +func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { + migrate, err := schema.NewMigrate(s.drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %v", err) + } + return migrate.Create(ctx, Tables...) +} + +// WriteTo writes the schema changes to w instead of running them against the database. +// +// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { +// log.Fatal(err) +// } +// +func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { + drv := &schema.WriteDriver{ + Writer: w, + Driver: s.drv, + } + migrate, err := schema.NewMigrate(drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %v", err) + } + return migrate.Create(ctx, Tables...) +} diff --git a/entc/integration/privacy/ent/migrate/schema.go b/entc/integration/privacy/ent/migrate/schema.go new file mode 100644 index 000000000..3b67a85e4 --- /dev/null +++ b/entc/integration/privacy/ent/migrate/schema.go @@ -0,0 +1,65 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package migrate + +import ( + "github.com/facebookincubator/ent/dialect/sql/schema" + "github.com/facebookincubator/ent/schema/field" +) + +var ( + // PlanetsColumns holds the columns for the "planets" table. + PlanetsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "name", Type: field.TypeString, Unique: true}, + {Name: "age", Type: field.TypeUint, Nullable: true}, + } + // PlanetsTable holds the schema information for the "planets" table. + PlanetsTable = &schema.Table{ + Name: "planets", + Columns: PlanetsColumns, + PrimaryKey: []*schema.Column{PlanetsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{}, + } + // PlanetNeighborsColumns holds the columns for the "planet_neighbors" table. + PlanetNeighborsColumns = []*schema.Column{ + {Name: "planet_id", Type: field.TypeInt}, + {Name: "neighbor_id", Type: field.TypeInt}, + } + // PlanetNeighborsTable holds the schema information for the "planet_neighbors" table. + PlanetNeighborsTable = &schema.Table{ + Name: "planet_neighbors", + Columns: PlanetNeighborsColumns, + PrimaryKey: []*schema.Column{PlanetNeighborsColumns[0], PlanetNeighborsColumns[1]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "planet_neighbors_planet_id", + Columns: []*schema.Column{PlanetNeighborsColumns[0]}, + + RefColumns: []*schema.Column{PlanetsColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "planet_neighbors_neighbor_id", + Columns: []*schema.Column{PlanetNeighborsColumns[1]}, + + RefColumns: []*schema.Column{PlanetsColumns[0]}, + OnDelete: schema.Cascade, + }, + }, + } + // Tables holds all the tables in the schema. + Tables = []*schema.Table{ + PlanetsTable, + PlanetNeighborsTable, + } +) + +func init() { + PlanetNeighborsTable.ForeignKeys[0].RefTable = PlanetsTable + PlanetNeighborsTable.ForeignKeys[1].RefTable = PlanetsTable +} diff --git a/entc/integration/privacy/ent/mutation.go b/entc/integration/privacy/ent/mutation.go new file mode 100644 index 000000000..5f5ebc2ca --- /dev/null +++ b/entc/integration/privacy/ent/mutation.go @@ -0,0 +1,416 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypePlanet = "Planet" +) + +// PlanetMutation represents an operation that mutate the Planets +// nodes in the graph. +type PlanetMutation struct { + config + op Op + typ string + id *int + name *string + age *uint + addage *uint + clearedFields map[string]bool + neighbors map[int]struct{} + removedneighbors map[int]struct{} +} + +var _ ent.Mutation = (*PlanetMutation)(nil) + +// newPlanetMutation creates new mutation for $n.Name. +func newPlanetMutation(c config, op Op) *PlanetMutation { + return &PlanetMutation{ + config: c, + op: op, + typ: TypePlanet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PlanetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PlanetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PlanetMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *PlanetMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *PlanetMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *PlanetMutation) ResetName() { + m.name = nil +} + +// SetAge sets the age field. +func (m *PlanetMutation) SetAge(u uint) { + m.age = &u + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *PlanetMutation) Age() (r uint, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds u to age. +func (m *PlanetMutation) AddAge(u uint) { + if m.addage != nil { + *m.addage += u + } else { + m.addage = &u + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *PlanetMutation) AddedAge() (r uint, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ClearAge clears the value of age. +func (m *PlanetMutation) ClearAge() { + m.age = nil + m.addage = nil + m.clearedFields[planet.FieldAge] = true +} + +// AgeCleared returns if the field age was cleared in this mutation. +func (m *PlanetMutation) AgeCleared() bool { + return m.clearedFields[planet.FieldAge] +} + +// ResetAge reset all changes of the age field. +func (m *PlanetMutation) ResetAge() { + m.age = nil + m.addage = nil + delete(m.clearedFields, planet.FieldAge) +} + +// AddNeighborIDs adds the neighbors edge to Planet by ids. +func (m *PlanetMutation) AddNeighborIDs(ids ...int) { + if m.neighbors == nil { + m.neighbors = make(map[int]struct{}) + } + for i := range ids { + m.neighbors[ids[i]] = struct{}{} + } +} + +// RemoveNeighborIDs removes the neighbors edge to Planet by ids. +func (m *PlanetMutation) RemoveNeighborIDs(ids ...int) { + if m.removedneighbors == nil { + m.removedneighbors = make(map[int]struct{}) + } + for i := range ids { + m.removedneighbors[ids[i]] = struct{}{} + } +} + +// RemovedNeighbors returns the removed ids of neighbors. +func (m *PlanetMutation) RemovedNeighborsIDs() (ids []int) { + for id := range m.removedneighbors { + ids = append(ids, id) + } + return +} + +// NeighborsIDs returns the neighbors ids in the mutation. +func (m *PlanetMutation) NeighborsIDs() (ids []int) { + for id := range m.neighbors { + ids = append(ids, id) + } + return +} + +// ResetNeighbors reset all changes of the neighbors edge. +func (m *PlanetMutation) ResetNeighbors() { + m.neighbors = nil + m.removedneighbors = nil +} + +// Op returns the operation name. +func (m *PlanetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Planet). +func (m *PlanetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PlanetMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.name != nil { + fields = append(fields, planet.FieldName) + } + if m.age != nil { + fields = append(fields, planet.FieldAge) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PlanetMutation) Field(name string) (ent.Value, bool) { + switch name { + case planet.FieldName: + return m.Name() + case planet.FieldAge: + return m.Age() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PlanetMutation) SetField(name string, value ent.Value) error { + switch name { + case planet.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case planet.FieldAge: + v, ok := value.(uint) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + } + return fmt.Errorf("unknown Planet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PlanetMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, planet.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PlanetMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case planet.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PlanetMutation) AddField(name string, value ent.Value) error { + switch name { + case planet.FieldAge: + v, ok := value.(uint) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown Planet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PlanetMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[planet.FieldAge] { + fields = append(fields, planet.FieldAge) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PlanetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PlanetMutation) ClearField(name string) error { + switch name { + case planet.FieldAge: + m.ClearAge() + return nil + } + return fmt.Errorf("unknown Planet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PlanetMutation) ResetField(name string) error { + switch name { + case planet.FieldName: + m.ResetName() + return nil + case planet.FieldAge: + m.ResetAge() + return nil + } + return fmt.Errorf("unknown Planet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PlanetMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.neighbors != nil { + edges = append(edges, planet.EdgeNeighbors) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PlanetMutation) AddedIDs(name string) []ent.Value { + switch name { + case planet.EdgeNeighbors: + ids := make([]ent.Value, 0, len(m.neighbors)) + for id := range m.neighbors { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PlanetMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedneighbors != nil { + edges = append(edges, planet.EdgeNeighbors) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PlanetMutation) RemovedIDs(name string) []ent.Value { + switch name { + case planet.EdgeNeighbors: + ids := make([]ent.Value, 0, len(m.removedneighbors)) + for id := range m.removedneighbors { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PlanetMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PlanetMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PlanetMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Planet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PlanetMutation) ResetEdge(name string) error { + switch name { + case planet.EdgeNeighbors: + m.ResetNeighbors() + return nil + } + return fmt.Errorf("unknown Planet edge %s", name) +} diff --git a/entc/integration/privacy/ent/planet.go b/entc/integration/privacy/ent/planet.go new file mode 100644 index 000000000..95d0ee00d --- /dev/null +++ b/entc/integration/privacy/ent/planet.go @@ -0,0 +1,126 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" +) + +// Planet is the model entity for the Planet schema. +type Planet struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Age holds the value of the "age" field. + Age uint `json:"age,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the PlanetQuery when eager-loading is set. + Edges PlanetEdges `json:"edges"` +} + +// PlanetEdges holds the relations/edges for other nodes in the graph. +type PlanetEdges struct { + // Neighbors holds the value of the neighbors edge. + Neighbors []*Planet + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// NeighborsOrErr returns the Neighbors value or an error if the edge +// was not loaded in eager-loading. +func (e PlanetEdges) NeighborsOrErr() ([]*Planet, error) { + if e.loadedTypes[0] { + return e.Neighbors, nil + } + return nil, &NotLoadedError{edge: "neighbors"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Planet) scanValues() []interface{} { + return []interface{}{ + &sql.NullInt64{}, // id + &sql.NullString{}, // name + &sql.NullInt64{}, // age + } +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Planet fields. +func (pl *Planet) assignValues(values ...interface{}) error { + if m, n := len(values), len(planet.Columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + value, ok := values[0].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + pl.ID = int(value.Int64) + values = values[1:] + if value, ok := values[0].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[0]) + } else if value.Valid { + pl.Name = value.String + } + if value, ok := values[1].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field age", values[1]) + } else if value.Valid { + pl.Age = uint(value.Int64) + } + return nil +} + +// QueryNeighbors queries the neighbors edge of the Planet. +func (pl *Planet) QueryNeighbors() *PlanetQuery { + return (&PlanetClient{config: pl.config}).QueryNeighbors(pl) +} + +// Update returns a builder for updating this Planet. +// Note that, you need to call Planet.Unwrap() before calling this method, if this Planet +// was returned from a transaction, and the transaction was committed or rolled back. +func (pl *Planet) Update() *PlanetUpdateOne { + return (&PlanetClient{config: pl.config}).UpdateOne(pl) +} + +// Unwrap unwraps the entity that was returned from a transaction after it was closed, +// so that all next queries will be executed through the driver which created the transaction. +func (pl *Planet) Unwrap() *Planet { + tx, ok := pl.config.driver.(*txDriver) + if !ok { + panic("ent: Planet is not a transactional entity") + } + pl.config.driver = tx.drv + return pl +} + +// String implements the fmt.Stringer. +func (pl *Planet) String() string { + var builder strings.Builder + builder.WriteString("Planet(") + builder.WriteString(fmt.Sprintf("id=%v", pl.ID)) + builder.WriteString(", name=") + builder.WriteString(pl.Name) + builder.WriteString(", age=") + builder.WriteString(fmt.Sprintf("%v", pl.Age)) + builder.WriteByte(')') + return builder.String() +} + +// Planets is a parsable slice of Planet. +type Planets []*Planet + +func (pl Planets) config(cfg config) { + for _i := range pl { + pl[_i].config = cfg + } +} diff --git a/entc/integration/privacy/ent/planet/planet.go b/entc/integration/privacy/ent/planet/planet.go new file mode 100644 index 000000000..a1334a6bd --- /dev/null +++ b/entc/integration/privacy/ent/planet/planet.go @@ -0,0 +1,53 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package planet + +import ( + "github.com/facebookincubator/ent" +) + +const ( + // Label holds the string label denoting the planet type in the database. + Label = "planet" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. + FieldName = "name" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" + + // EdgeNeighbors holds the string denoting the neighbors edge name in mutations. + EdgeNeighbors = "neighbors" + + // Table holds the table name of the planet in the database. + Table = "planets" + // NeighborsTable is the table the holds the neighbors relation/edge. The primary key declared below. + NeighborsTable = "planet_neighbors" +) + +// Columns holds all SQL columns for planet fields. +var Columns = []string{ + FieldID, + FieldName, + FieldAge, +} + +var ( + // NeighborsPrimaryKey and NeighborsColumn2 are the table columns denoting the + // primary key for the neighbors relation (M2M). + NeighborsPrimaryKey = []string{"planet_id", "neighbor_id"} +) + +// Note that the variables below are initialized by the runtime +// package on the initialization of the application. Therefore, +// it should be imported in the main as follows: +// +// import _ "github.com/facebookincubator/ent/entc/integration/privacy/ent/runtime" +// +var ( + Hooks [2]ent.Hook + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error +) diff --git a/entc/integration/privacy/ent/planet/where.go b/entc/integration/privacy/ent/planet/where.go new file mode 100644 index 000000000..2d2f944e4 --- /dev/null +++ b/entc/integration/privacy/ent/planet/where.go @@ -0,0 +1,371 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package planet + +import ( + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/predicate" +) + +// ID filters vertices based on their identifier. +func ID(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldID), id)) + }) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.In(s.C(FieldID), v...)) + }) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.NotIn(s.C(FieldID), v...)) + }) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldID), id)) + }) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldID), id)) + }) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldID), id)) + }) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldID), id)) + }) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldName), v)) + }) +} + +// Age applies equality check predicate on the "age" field. It's identical to AgeEQ. +func Age(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldAge), v)) + }) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldName), v)) + }) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldName), v)) + }) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.Planet { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Planet(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldName), v...)) + }) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.Planet { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Planet(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldName), v...)) + }) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldName), v)) + }) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldName), v)) + }) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldName), v)) + }) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldName), v)) + }) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.Contains(s.C(FieldName), v)) + }) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.HasPrefix(s.C(FieldName), v)) + }) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.HasSuffix(s.C(FieldName), v)) + }) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EqualFold(s.C(FieldName), v)) + }) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.ContainsFold(s.C(FieldName), v)) + }) +} + +// AgeEQ applies the EQ predicate on the "age" field. +func AgeEQ(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldAge), v)) + }) +} + +// AgeNEQ applies the NEQ predicate on the "age" field. +func AgeNEQ(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldAge), v)) + }) +} + +// AgeIn applies the In predicate on the "age" field. +func AgeIn(vs ...uint) predicate.Planet { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Planet(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldAge), v...)) + }) +} + +// AgeNotIn applies the NotIn predicate on the "age" field. +func AgeNotIn(vs ...uint) predicate.Planet { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Planet(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(vs) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldAge), v...)) + }) +} + +// AgeGT applies the GT predicate on the "age" field. +func AgeGT(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldAge), v)) + }) +} + +// AgeGTE applies the GTE predicate on the "age" field. +func AgeGTE(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldAge), v)) + }) +} + +// AgeLT applies the LT predicate on the "age" field. +func AgeLT(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldAge), v)) + }) +} + +// AgeLTE applies the LTE predicate on the "age" field. +func AgeLTE(v uint) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldAge), v)) + }) +} + +// AgeIsNil applies the IsNil predicate on the "age" field. +func AgeIsNil() predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldAge))) + }) +} + +// AgeNotNil applies the NotNil predicate on the "age" field. +func AgeNotNil() predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldAge))) + }) +} + +// HasNeighbors applies the HasEdge predicate on the "neighbors" edge. +func HasNeighbors() predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(NeighborsTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, NeighborsTable, NeighborsPrimaryKey...), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasNeighborsWith applies the HasEdge predicate on the "neighbors" edge with a given conditions (other predicates). +func HasNeighborsWith(preds ...predicate.Planet) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, NeighborsTable, NeighborsPrimaryKey...), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups list of predicates with the AND operator between them. +func And(predicates ...predicate.Planet) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for _, p := range predicates { + p(s1) + } + s.Where(s1.P()) + }) +} + +// Or groups list of predicates with the OR operator between them. +func Or(predicates ...predicate.Planet) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for i, p := range predicates { + if i > 0 { + s1.Or() + } + p(s1) + } + s.Where(s1.P()) + }) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Planet) predicate.Planet { + return predicate.Planet(func(s *sql.Selector) { + p(s.Not()) + }) +} diff --git a/entc/integration/privacy/ent/planet_create.go b/entc/integration/privacy/ent/planet_create.go new file mode 100644 index 000000000..5d91455b6 --- /dev/null +++ b/entc/integration/privacy/ent/planet_create.go @@ -0,0 +1,161 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + "github.com/facebookincubator/ent/schema/field" +) + +// PlanetCreate is the builder for creating a Planet entity. +type PlanetCreate struct { + config + mutation *PlanetMutation + hooks []Hook +} + +// SetName sets the name field. +func (pc *PlanetCreate) SetName(s string) *PlanetCreate { + pc.mutation.SetName(s) + return pc +} + +// SetAge sets the age field. +func (pc *PlanetCreate) SetAge(u uint) *PlanetCreate { + pc.mutation.SetAge(u) + return pc +} + +// SetNillableAge sets the age field if the given value is not nil. +func (pc *PlanetCreate) SetNillableAge(u *uint) *PlanetCreate { + if u != nil { + pc.SetAge(*u) + } + return pc +} + +// AddNeighborIDs adds the neighbors edge to Planet by ids. +func (pc *PlanetCreate) AddNeighborIDs(ids ...int) *PlanetCreate { + pc.mutation.AddNeighborIDs(ids...) + return pc +} + +// AddNeighbors adds the neighbors edges to Planet. +func (pc *PlanetCreate) AddNeighbors(p ...*Planet) *PlanetCreate { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return pc.AddNeighborIDs(ids...) +} + +// Save creates the Planet in the database. +func (pc *PlanetCreate) Save(ctx context.Context) (*Planet, error) { + if _, ok := pc.mutation.Name(); !ok { + return nil, errors.New("ent: missing required field \"name\"") + } + if v, ok := pc.mutation.Name(); ok { + if err := planet.NameValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + } + } + var ( + err error + node *Planet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PlanetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX calls Save and panics if Save returns an error. +func (pc *PlanetCreate) SaveX(ctx context.Context) *Planet { + v, err := pc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +func (pc *PlanetCreate) sqlSave(ctx context.Context) (*Planet, error) { + var ( + pl = &Planet{config: pc.config} + _spec = &sqlgraph.CreateSpec{ + Table: planet.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + } + ) + if value, ok := pc.mutation.Name(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: planet.FieldName, + }) + pl.Name = value + } + if value, ok := pc.mutation.Age(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Value: value, + Column: planet.FieldAge, + }) + pl.Age = value + } + if nodes := pc.mutation.NeighborsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: planet.NeighborsTable, + Columns: planet.NeighborsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if err := sqlgraph.CreateNode(ctx, pc.driver, _spec); err != nil { + if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return nil, err + } + id := _spec.ID.Value.(int64) + pl.ID = int(id) + return pl, nil +} diff --git a/entc/integration/privacy/ent/planet_delete.go b/entc/integration/privacy/ent/planet_delete.go new file mode 100644 index 000000000..29b669f93 --- /dev/null +++ b/entc/integration/privacy/ent/planet_delete.go @@ -0,0 +1,112 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/predicate" + "github.com/facebookincubator/ent/schema/field" +) + +// PlanetDelete is the builder for deleting a Planet entity. +type PlanetDelete struct { + config + hooks []Hook + mutation *PlanetMutation + predicates []predicate.Planet +} + +// Where adds a new predicate to the delete builder. +func (pd *PlanetDelete) Where(ps ...predicate.Planet) *PlanetDelete { + pd.predicates = append(pd.predicates, ps...) + return pd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (pd *PlanetDelete) Exec(ctx context.Context) (int, error) { + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PlanetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// ExecX is like Exec, but panics if an error occurs. +func (pd *PlanetDelete) ExecX(ctx context.Context) int { + n, err := pd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (pd *PlanetDelete) sqlExec(ctx context.Context) (int, error) { + _spec := &sqlgraph.DeleteSpec{ + Node: &sqlgraph.NodeSpec{ + Table: planet.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + if ps := pd.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return sqlgraph.DeleteNodes(ctx, pd.driver, _spec) +} + +// PlanetDeleteOne is the builder for deleting a single Planet entity. +type PlanetDeleteOne struct { + pd *PlanetDelete +} + +// Exec executes the deletion query. +func (pdo *PlanetDeleteOne) Exec(ctx context.Context) error { + n, err := pdo.pd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{planet.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (pdo *PlanetDeleteOne) ExecX(ctx context.Context) { + pdo.pd.ExecX(ctx) +} diff --git a/entc/integration/privacy/ent/planet_query.go b/entc/integration/privacy/ent/planet_query.go new file mode 100644 index 000000000..176ab224b --- /dev/null +++ b/entc/integration/privacy/ent/planet_query.go @@ -0,0 +1,712 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "errors" + "fmt" + "math" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/predicate" + "github.com/facebookincubator/ent/schema/field" +) + +// PlanetQuery is the builder for querying Planet entities. +type PlanetQuery struct { + config + limit *int + offset *int + order []Order + unique []string + predicates []predicate.Planet + // eager-loading edges. + withNeighbors *PlanetQuery + // intermediate query. + sql *sql.Selector +} + +// Where adds a new predicate for the builder. +func (pq *PlanetQuery) Where(ps ...predicate.Planet) *PlanetQuery { + pq.predicates = append(pq.predicates, ps...) + return pq +} + +// Limit adds a limit step to the query. +func (pq *PlanetQuery) Limit(limit int) *PlanetQuery { + pq.limit = &limit + return pq +} + +// Offset adds an offset step to the query. +func (pq *PlanetQuery) Offset(offset int) *PlanetQuery { + pq.offset = &offset + return pq +} + +// Order adds an order step to the query. +func (pq *PlanetQuery) Order(o ...Order) *PlanetQuery { + pq.order = append(pq.order, o...) + return pq +} + +// QueryNeighbors chains the current query on the neighbors edge. +func (pq *PlanetQuery) QueryNeighbors() *PlanetQuery { + query := &PlanetQuery{config: pq.config} + step := sqlgraph.NewStep( + sqlgraph.From(planet.Table, planet.FieldID, pq.sqlQuery()), + sqlgraph.To(planet.Table, planet.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, planet.NeighborsTable, planet.NeighborsPrimaryKey...), + ) + query.sql = sqlgraph.SetNeighbors(pq.driver.Dialect(), step) + return query +} + +// First returns the first Planet entity in the query. Returns *NotFoundError when no planet was found. +func (pq *PlanetQuery) First(ctx context.Context) (*Planet, error) { + pls, err := pq.Limit(1).All(ctx) + if err != nil { + return nil, err + } + if len(pls) == 0 { + return nil, &NotFoundError{planet.Label} + } + return pls[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (pq *PlanetQuery) FirstX(ctx context.Context) *Planet { + pl, err := pq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return pl +} + +// FirstID returns the first Planet id in the query. Returns *NotFoundError when no id was found. +func (pq *PlanetQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = pq.Limit(1).IDs(ctx); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{planet.Label} + return + } + return ids[0], nil +} + +// FirstXID is like FirstID, but panics if an error occurs. +func (pq *PlanetQuery) FirstXID(ctx context.Context) int { + id, err := pq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns the only Planet entity in the query, returns an error if not exactly one entity was returned. +func (pq *PlanetQuery) Only(ctx context.Context) (*Planet, error) { + pls, err := pq.Limit(2).All(ctx) + if err != nil { + return nil, err + } + switch len(pls) { + case 1: + return pls[0], nil + case 0: + return nil, &NotFoundError{planet.Label} + default: + return nil, &NotSingularError{planet.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (pq *PlanetQuery) OnlyX(ctx context.Context) *Planet { + pl, err := pq.Only(ctx) + if err != nil { + panic(err) + } + return pl +} + +// OnlyID returns the only Planet id in the query, returns an error if not exactly one id was returned. +func (pq *PlanetQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = pq.Limit(2).IDs(ctx); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{planet.Label} + default: + err = &NotSingularError{planet.Label} + } + return +} + +// OnlyXID is like OnlyID, but panics if an error occurs. +func (pq *PlanetQuery) OnlyXID(ctx context.Context) int { + id, err := pq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Planets. +func (pq *PlanetQuery) All(ctx context.Context) ([]*Planet, error) { + return pq.sqlAll(ctx) +} + +// AllX is like All, but panics if an error occurs. +func (pq *PlanetQuery) AllX(ctx context.Context) []*Planet { + pls, err := pq.All(ctx) + if err != nil { + panic(err) + } + return pls +} + +// IDs executes the query and returns a list of Planet ids. +func (pq *PlanetQuery) IDs(ctx context.Context) ([]int, error) { + var ids []int + if err := pq.Select(planet.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (pq *PlanetQuery) IDsX(ctx context.Context) []int { + ids, err := pq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (pq *PlanetQuery) Count(ctx context.Context) (int, error) { + return pq.sqlCount(ctx) +} + +// CountX is like Count, but panics if an error occurs. +func (pq *PlanetQuery) CountX(ctx context.Context) int { + count, err := pq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (pq *PlanetQuery) Exist(ctx context.Context) (bool, error) { + return pq.sqlExist(ctx) +} + +// ExistX is like Exist, but panics if an error occurs. +func (pq *PlanetQuery) ExistX(ctx context.Context) bool { + exist, err := pq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the query builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (pq *PlanetQuery) Clone() *PlanetQuery { + return &PlanetQuery{ + config: pq.config, + limit: pq.limit, + offset: pq.offset, + order: append([]Order{}, pq.order...), + unique: append([]string{}, pq.unique...), + predicates: append([]predicate.Planet{}, pq.predicates...), + // clone intermediate query. + sql: pq.sql.Clone(), + } +} + +// WithNeighbors tells the query-builder to eager-loads the nodes that are connected to +// the "neighbors" edge. The optional arguments used to configure the query builder of the edge. +func (pq *PlanetQuery) WithNeighbors(opts ...func(*PlanetQuery)) *PlanetQuery { + query := &PlanetQuery{config: pq.config} + for _, opt := range opts { + opt(query) + } + pq.withNeighbors = query + return pq +} + +// GroupBy used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Planet.Query(). +// GroupBy(planet.FieldName). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +// +func (pq *PlanetQuery) GroupBy(field string, fields ...string) *PlanetGroupBy { + group := &PlanetGroupBy{config: pq.config} + group.fields = append([]string{field}, fields...) + group.sql = pq.sqlQuery() + return group +} + +// Select one or more fields from the given query. +// +// Example: +// +// var v []struct { +// Name string `json:"name,omitempty"` +// } +// +// client.Planet.Query(). +// Select(planet.FieldName). +// Scan(ctx, &v) +// +func (pq *PlanetQuery) Select(field string, fields ...string) *PlanetSelect { + selector := &PlanetSelect{config: pq.config} + selector.fields = append([]string{field}, fields...) + selector.sql = pq.sqlQuery() + return selector +} + +func (pq *PlanetQuery) sqlAll(ctx context.Context) ([]*Planet, error) { + var ( + nodes = []*Planet{} + _spec = pq.querySpec() + loadedTypes = [1]bool{ + pq.withNeighbors != nil, + } + ) + _spec.ScanValues = func() []interface{} { + node := &Planet{config: pq.config} + nodes = append(nodes, node) + values := node.scanValues() + return values + } + _spec.Assign = func(values ...interface{}) error { + if len(nodes) == 0 { + return fmt.Errorf("ent: Assign called without calling ScanValues") + } + node := nodes[len(nodes)-1] + node.Edges.loadedTypes = loadedTypes + return node.assignValues(values...) + } + if err := sqlgraph.QueryNodes(ctx, pq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + + if query := pq.withNeighbors; query != nil { + fks := make([]driver.Value, 0, len(nodes)) + ids := make(map[int]*Planet, len(nodes)) + for _, node := range nodes { + ids[node.ID] = node + fks = append(fks, node.ID) + } + var ( + edgeids []int + edges = make(map[int][]*Planet) + ) + _spec := &sqlgraph.EdgeQuerySpec{ + Edge: &sqlgraph.EdgeSpec{ + Inverse: false, + Table: planet.NeighborsTable, + Columns: planet.NeighborsPrimaryKey, + }, + Predicate: func(s *sql.Selector) { + s.Where(sql.InValues(planet.NeighborsPrimaryKey[0], fks...)) + }, + + ScanValues: func() [2]interface{} { + return [2]interface{}{&sql.NullInt64{}, &sql.NullInt64{}} + }, + Assign: func(out, in interface{}) error { + eout, ok := out.(*sql.NullInt64) + if !ok || eout == nil { + return fmt.Errorf("unexpected id value for edge-out") + } + ein, ok := in.(*sql.NullInt64) + if !ok || ein == nil { + return fmt.Errorf("unexpected id value for edge-in") + } + outValue := int(eout.Int64) + inValue := int(ein.Int64) + node, ok := ids[outValue] + if !ok { + return fmt.Errorf("unexpected node id in edges: %v", outValue) + } + edgeids = append(edgeids, inValue) + edges[inValue] = append(edges[inValue], node) + return nil + }, + } + if err := sqlgraph.QueryEdges(ctx, pq.driver, _spec); err != nil { + return nil, fmt.Errorf(`query edges "neighbors": %v`, err) + } + query.Where(planet.IDIn(edgeids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := edges[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected "neighbors" node returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.Neighbors = append(nodes[i].Edges.Neighbors, n) + } + } + } + + return nodes, nil +} + +func (pq *PlanetQuery) sqlCount(ctx context.Context) (int, error) { + _spec := pq.querySpec() + return sqlgraph.CountNodes(ctx, pq.driver, _spec) +} + +func (pq *PlanetQuery) sqlExist(ctx context.Context) (bool, error) { + n, err := pq.sqlCount(ctx) + if err != nil { + return false, fmt.Errorf("ent: check existence: %v", err) + } + return n > 0, nil +} + +func (pq *PlanetQuery) querySpec() *sqlgraph.QuerySpec { + _spec := &sqlgraph.QuerySpec{ + Node: &sqlgraph.NodeSpec{ + Table: planet.Table, + Columns: planet.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + From: pq.sql, + Unique: true, + } + if ps := pq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := pq.limit; limit != nil { + _spec.Limit = *limit + } + if offset := pq.offset; offset != nil { + _spec.Offset = *offset + } + if ps := pq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (pq *PlanetQuery) sqlQuery() *sql.Selector { + builder := sql.Dialect(pq.driver.Dialect()) + t1 := builder.Table(planet.Table) + selector := builder.Select(t1.Columns(planet.Columns...)...).From(t1) + if pq.sql != nil { + selector = pq.sql + selector.Select(selector.Columns(planet.Columns...)...) + } + for _, p := range pq.predicates { + p(selector) + } + for _, p := range pq.order { + p(selector) + } + if offset := pq.offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := pq.limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// PlanetGroupBy is the builder for group-by Planet entities. +type PlanetGroupBy struct { + config + fields []string + fns []Aggregate + // intermediate query. + sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (pgb *PlanetGroupBy) Aggregate(fns ...Aggregate) *PlanetGroupBy { + pgb.fns = append(pgb.fns, fns...) + return pgb +} + +// Scan applies the group-by query and scan the result into the given value. +func (pgb *PlanetGroupBy) Scan(ctx context.Context, v interface{}) error { + return pgb.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (pgb *PlanetGroupBy) ScanX(ctx context.Context, v interface{}) { + if err := pgb.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from group-by. It is only allowed when querying group-by with one field. +func (pgb *PlanetGroupBy) Strings(ctx context.Context) ([]string, error) { + if len(pgb.fields) > 1 { + return nil, errors.New("ent: PlanetGroupBy.Strings is not achievable when grouping more than 1 field") + } + var v []string + if err := pgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (pgb *PlanetGroupBy) StringsX(ctx context.Context) []string { + v, err := pgb.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from group-by. It is only allowed when querying group-by with one field. +func (pgb *PlanetGroupBy) Ints(ctx context.Context) ([]int, error) { + if len(pgb.fields) > 1 { + return nil, errors.New("ent: PlanetGroupBy.Ints is not achievable when grouping more than 1 field") + } + var v []int + if err := pgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (pgb *PlanetGroupBy) IntsX(ctx context.Context) []int { + v, err := pgb.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from group-by. It is only allowed when querying group-by with one field. +func (pgb *PlanetGroupBy) Float64s(ctx context.Context) ([]float64, error) { + if len(pgb.fields) > 1 { + return nil, errors.New("ent: PlanetGroupBy.Float64s is not achievable when grouping more than 1 field") + } + var v []float64 + if err := pgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (pgb *PlanetGroupBy) Float64sX(ctx context.Context) []float64 { + v, err := pgb.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from group-by. It is only allowed when querying group-by with one field. +func (pgb *PlanetGroupBy) Bools(ctx context.Context) ([]bool, error) { + if len(pgb.fields) > 1 { + return nil, errors.New("ent: PlanetGroupBy.Bools is not achievable when grouping more than 1 field") + } + var v []bool + if err := pgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (pgb *PlanetGroupBy) BoolsX(ctx context.Context) []bool { + v, err := pgb.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (pgb *PlanetGroupBy) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := pgb.sqlQuery().Query() + if err := pgb.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (pgb *PlanetGroupBy) sqlQuery() *sql.Selector { + selector := pgb.sql + columns := make([]string, 0, len(pgb.fields)+len(pgb.fns)) + columns = append(columns, pgb.fields...) + for _, fn := range pgb.fns { + columns = append(columns, fn(selector)) + } + return selector.Select(columns...).GroupBy(pgb.fields...) +} + +// PlanetSelect is the builder for select fields of Planet entities. +type PlanetSelect struct { + config + fields []string + // intermediate queries. + sql *sql.Selector +} + +// Scan applies the selector query and scan the result into the given value. +func (ps *PlanetSelect) Scan(ctx context.Context, v interface{}) error { + return ps.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (ps *PlanetSelect) ScanX(ctx context.Context, v interface{}) { + if err := ps.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from selector. It is only allowed when selecting one field. +func (ps *PlanetSelect) Strings(ctx context.Context) ([]string, error) { + if len(ps.fields) > 1 { + return nil, errors.New("ent: PlanetSelect.Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := ps.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (ps *PlanetSelect) StringsX(ctx context.Context) []string { + v, err := ps.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from selector. It is only allowed when selecting one field. +func (ps *PlanetSelect) Ints(ctx context.Context) ([]int, error) { + if len(ps.fields) > 1 { + return nil, errors.New("ent: PlanetSelect.Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := ps.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (ps *PlanetSelect) IntsX(ctx context.Context) []int { + v, err := ps.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from selector. It is only allowed when selecting one field. +func (ps *PlanetSelect) Float64s(ctx context.Context) ([]float64, error) { + if len(ps.fields) > 1 { + return nil, errors.New("ent: PlanetSelect.Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := ps.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (ps *PlanetSelect) Float64sX(ctx context.Context) []float64 { + v, err := ps.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from selector. It is only allowed when selecting one field. +func (ps *PlanetSelect) Bools(ctx context.Context) ([]bool, error) { + if len(ps.fields) > 1 { + return nil, errors.New("ent: PlanetSelect.Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := ps.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (ps *PlanetSelect) BoolsX(ctx context.Context) []bool { + v, err := ps.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (ps *PlanetSelect) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := ps.sqlQuery().Query() + if err := ps.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (ps *PlanetSelect) sqlQuery() sql.Querier { + selector := ps.sql + selector.Select(selector.Columns(ps.fields...)...) + return selector +} diff --git a/entc/integration/privacy/ent/planet_update.go b/entc/integration/privacy/ent/planet_update.go new file mode 100644 index 000000000..1a92acd2e --- /dev/null +++ b/entc/integration/privacy/ent/planet_update.go @@ -0,0 +1,430 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/dialect/sql/sqlgraph" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/predicate" + "github.com/facebookincubator/ent/schema/field" +) + +// PlanetUpdate is the builder for updating Planet entities. +type PlanetUpdate struct { + config + hooks []Hook + mutation *PlanetMutation + predicates []predicate.Planet +} + +// Where adds a new predicate for the builder. +func (pu *PlanetUpdate) Where(ps ...predicate.Planet) *PlanetUpdate { + pu.predicates = append(pu.predicates, ps...) + return pu +} + +// SetAge sets the age field. +func (pu *PlanetUpdate) SetAge(u uint) *PlanetUpdate { + pu.mutation.ResetAge() + pu.mutation.SetAge(u) + return pu +} + +// SetNillableAge sets the age field if the given value is not nil. +func (pu *PlanetUpdate) SetNillableAge(u *uint) *PlanetUpdate { + if u != nil { + pu.SetAge(*u) + } + return pu +} + +// AddAge adds u to age. +func (pu *PlanetUpdate) AddAge(u uint) *PlanetUpdate { + pu.mutation.AddAge(u) + return pu +} + +// ClearAge clears the value of age. +func (pu *PlanetUpdate) ClearAge() *PlanetUpdate { + pu.mutation.ClearAge() + return pu +} + +// AddNeighborIDs adds the neighbors edge to Planet by ids. +func (pu *PlanetUpdate) AddNeighborIDs(ids ...int) *PlanetUpdate { + pu.mutation.AddNeighborIDs(ids...) + return pu +} + +// AddNeighbors adds the neighbors edges to Planet. +func (pu *PlanetUpdate) AddNeighbors(p ...*Planet) *PlanetUpdate { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return pu.AddNeighborIDs(ids...) +} + +// RemoveNeighborIDs removes the neighbors edge to Planet by ids. +func (pu *PlanetUpdate) RemoveNeighborIDs(ids ...int) *PlanetUpdate { + pu.mutation.RemoveNeighborIDs(ids...) + return pu +} + +// RemoveNeighbors removes neighbors edges to Planet. +func (pu *PlanetUpdate) RemoveNeighbors(p ...*Planet) *PlanetUpdate { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return pu.RemoveNeighborIDs(ids...) +} + +// Save executes the query and returns the number of rows/vertices matched by this operation. +func (pu *PlanetUpdate) Save(ctx context.Context) (int, error) { + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PlanetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// SaveX is like Save, but panics if an error occurs. +func (pu *PlanetUpdate) SaveX(ctx context.Context) int { + affected, err := pu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (pu *PlanetUpdate) Exec(ctx context.Context) error { + _, err := pu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (pu *PlanetUpdate) ExecX(ctx context.Context) { + if err := pu.Exec(ctx); err != nil { + panic(err) + } +} + +func (pu *PlanetUpdate) sqlSave(ctx context.Context) (n int, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: planet.Table, + Columns: planet.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + if ps := pu.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := pu.mutation.Age(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Value: value, + Column: planet.FieldAge, + }) + } + if value, ok := pu.mutation.AddedAge(); ok { + _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Value: value, + Column: planet.FieldAge, + }) + } + if pu.mutation.AgeCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Column: planet.FieldAge, + }) + } + if nodes := pu.mutation.RemovedNeighborsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: planet.NeighborsTable, + Columns: planet.NeighborsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := pu.mutation.NeighborsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: planet.NeighborsTable, + Columns: planet.NeighborsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if n, err = sqlgraph.UpdateNodes(ctx, pu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{planet.Label} + } else if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return 0, err + } + return n, nil +} + +// PlanetUpdateOne is the builder for updating a single Planet entity. +type PlanetUpdateOne struct { + config + hooks []Hook + mutation *PlanetMutation +} + +// SetAge sets the age field. +func (puo *PlanetUpdateOne) SetAge(u uint) *PlanetUpdateOne { + puo.mutation.ResetAge() + puo.mutation.SetAge(u) + return puo +} + +// SetNillableAge sets the age field if the given value is not nil. +func (puo *PlanetUpdateOne) SetNillableAge(u *uint) *PlanetUpdateOne { + if u != nil { + puo.SetAge(*u) + } + return puo +} + +// AddAge adds u to age. +func (puo *PlanetUpdateOne) AddAge(u uint) *PlanetUpdateOne { + puo.mutation.AddAge(u) + return puo +} + +// ClearAge clears the value of age. +func (puo *PlanetUpdateOne) ClearAge() *PlanetUpdateOne { + puo.mutation.ClearAge() + return puo +} + +// AddNeighborIDs adds the neighbors edge to Planet by ids. +func (puo *PlanetUpdateOne) AddNeighborIDs(ids ...int) *PlanetUpdateOne { + puo.mutation.AddNeighborIDs(ids...) + return puo +} + +// AddNeighbors adds the neighbors edges to Planet. +func (puo *PlanetUpdateOne) AddNeighbors(p ...*Planet) *PlanetUpdateOne { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return puo.AddNeighborIDs(ids...) +} + +// RemoveNeighborIDs removes the neighbors edge to Planet by ids. +func (puo *PlanetUpdateOne) RemoveNeighborIDs(ids ...int) *PlanetUpdateOne { + puo.mutation.RemoveNeighborIDs(ids...) + return puo +} + +// RemoveNeighbors removes neighbors edges to Planet. +func (puo *PlanetUpdateOne) RemoveNeighbors(p ...*Planet) *PlanetUpdateOne { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return puo.RemoveNeighborIDs(ids...) +} + +// Save executes the query and returns the updated entity. +func (puo *PlanetUpdateOne) Save(ctx context.Context) (*Planet, error) { + + var ( + err error + node *Planet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PlanetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX is like Save, but panics if an error occurs. +func (puo *PlanetUpdateOne) SaveX(ctx context.Context) *Planet { + pl, err := puo.Save(ctx) + if err != nil { + panic(err) + } + return pl +} + +// Exec executes the query on the entity. +func (puo *PlanetUpdateOne) Exec(ctx context.Context) error { + _, err := puo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (puo *PlanetUpdateOne) ExecX(ctx context.Context) { + if err := puo.Exec(ctx); err != nil { + panic(err) + } +} + +func (puo *PlanetUpdateOne) sqlSave(ctx context.Context) (pl *Planet, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: planet.Table, + Columns: planet.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Planet.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := puo.mutation.Age(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Value: value, + Column: planet.FieldAge, + }) + } + if value, ok := puo.mutation.AddedAge(); ok { + _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Value: value, + Column: planet.FieldAge, + }) + } + if puo.mutation.AgeCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeUint, + Column: planet.FieldAge, + }) + } + if nodes := puo.mutation.RemovedNeighborsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: planet.NeighborsTable, + Columns: planet.NeighborsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := puo.mutation.NeighborsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: planet.NeighborsTable, + Columns: planet.NeighborsPrimaryKey, + Bidi: true, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: planet.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + pl = &Planet{config: puo.config} + _spec.Assign = pl.assignValues + _spec.ScanValues = pl.scanValues() + if err = sqlgraph.UpdateNode(ctx, puo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{planet.Label} + } else if cerr, ok := isSQLConstraintError(err); ok { + err = cerr + } + return nil, err + } + return pl, nil +} diff --git a/entc/integration/privacy/ent/predicate/predicate.go b/entc/integration/privacy/ent/predicate/predicate.go new file mode 100644 index 000000000..ed57b7031 --- /dev/null +++ b/entc/integration/privacy/ent/predicate/predicate.go @@ -0,0 +1,14 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package predicate + +import ( + "github.com/facebookincubator/ent/dialect/sql" +) + +// Planet is the predicate function for planet builders. +type Planet func(*sql.Selector) diff --git a/entc/integration/privacy/ent/privacy/privacy.go b/entc/integration/privacy/ent/privacy/privacy.go new file mode 100644 index 000000000..cc9219a8b --- /dev/null +++ b/entc/integration/privacy/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/privacy/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The PlanetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PlanetReadRuleFunc func(context.Context, *ent.Planet) error + +// EvalRead calls f(ctx, v). +func (f PlanetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Planet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Planet", v) +} + +// The PlanetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PlanetWriteRuleFunc func(context.Context, *ent.PlanetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PlanetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PlanetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PlanetMutation", m) +} diff --git a/entc/integration/privacy/ent/runtime.go b/entc/integration/privacy/ent/runtime.go new file mode 100644 index 000000000..fe1319e9d --- /dev/null +++ b/entc/integration/privacy/ent/runtime.go @@ -0,0 +1,9 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/privacy/ent/runtime/runtime.go diff --git a/entc/integration/privacy/ent/runtime/runtime.go b/entc/integration/privacy/ent/runtime/runtime.go new file mode 100644 index 000000000..bb73a3f91 --- /dev/null +++ b/entc/integration/privacy/ent/runtime/runtime.go @@ -0,0 +1,43 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +import ( + "context" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/schema" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + policy := schema.Planet{}.Policy() + planet.Hooks[0] = func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if err := policy.EvalWrite(ctx, m); err != nil { + return nil, err + } + return next.Mutate(ctx, m) + }) + } + planetHooks := schema.Planet{}.Hooks() + for i, h := range planetHooks { + planet.Hooks[i+1] = h + } + planetFields := schema.Planet{}.Fields() + // planetDescName is the schema descriptor for name field. + planetDescName := planetFields[0].Descriptor() + // planet.NameValidator is a validator for the "name" field. It is called by the builders before save. + planet.NameValidator = planetDescName.Validators[0].(func(string) error) +} + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/privacy/ent/schema/planet.go b/entc/integration/privacy/ent/schema/planet.go new file mode 100644 index 000000000..4e71d2551 --- /dev/null +++ b/entc/integration/privacy/ent/schema/planet.go @@ -0,0 +1,50 @@ +package schema + +import ( + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/privacy" + "github.com/facebookincubator/ent/entc/integration/privacy/rule" + "github.com/facebookincubator/ent/schema/edge" + "github.com/facebookincubator/ent/schema/field" +) + +// Planet defines the schema of a rule. +type Planet struct { + ent.Schema +} + +func (Planet) Fields() []ent.Field { + return []ent.Field{ + field.String("name"). + Immutable(). + NotEmpty(). + Unique(), + field.Uint("age"). + Optional(), + } +} + +func (Planet) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("neighbors", Planet.Type), + } +} + +func (Planet) Hooks() []ent.Hook { + return []ent.Hook{ + rule.LogPlanetMutationHook(), + } +} + +func (Planet) Policy() ent.Policy { + return privacy.Policy{ + Write: privacy.WritePolicy{ + rule.DenyUpdateRule(), + rule.DenyPlanetSelfLinkRule(), + privacy.AlwaysAllowRule(), + }, + Read: privacy.ReadPolicy{ + privacy.AlwaysAllowRule(), + }, + } +} diff --git a/entc/integration/privacy/ent/tx.go b/entc/integration/privacy/ent/tx.go new file mode 100644 index 000000000..ade96ebba --- /dev/null +++ b/entc/integration/privacy/ent/tx.go @@ -0,0 +1,98 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + + "github.com/facebookincubator/ent/dialect" +) + +// Tx is a transactional client that is created by calling Client.Tx(). +type Tx struct { + config + // Planet is the client for interacting with the Planet builders. + Planet *PlanetClient +} + +// Commit commits the transaction. +func (tx *Tx) Commit() error { + return tx.config.driver.(*txDriver).tx.Commit() +} + +// Rollback rollbacks the transaction. +func (tx *Tx) Rollback() error { + return tx.config.driver.(*txDriver).tx.Rollback() +} + +// Client returns a Client that binds to current transaction. +func (tx *Tx) Client() *Client { + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Planet = NewPlanetClient(tx.config) +} + +// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. +// The idea is to support transactions without adding any extra code to the builders. +// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. +// Commit and Rollback are nop for the internal builders and the user must call one +// of them in order to commit or rollback the transaction. +// +// If a closed transaction is embedded in one of the generated entities, and the entity +// applies a query, for example: Planet.QueryXXX(), the query will be executed +// through the driver which created this transaction. +// +// Note that txDriver is not goroutine safe. +type txDriver struct { + // the driver we started the transaction from. + drv dialect.Driver + // tx is the underlying transaction. + tx dialect.Tx +} + +// newTx creates a new transactional driver. +func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { + tx, err := drv.Tx(ctx) + if err != nil { + return nil, err + } + return &txDriver{tx: tx, drv: drv}, nil +} + +// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls +// from the internal builders. Should be called only by the internal builders. +func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } + +// Dialect returns the dialect of the driver we started the transaction from. +func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } + +// Close is a nop close. +func (*txDriver) Close() error { return nil } + +// Commit is a nop commit for the internal builders. +// User must call `Tx.Commit` in order to commit the transaction. +func (*txDriver) Commit() error { return nil } + +// Rollback is a nop rollback for the internal builders. +// User must call `Tx.Rollback` in order to rollback the transaction. +func (*txDriver) Rollback() error { return nil } + +// Exec calls tx.Exec. +func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error { + return tx.tx.Exec(ctx, query, args, v) +} + +// Query calls tx.Query. +func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error { + return tx.tx.Query(ctx, query, args, v) +} + +var _ dialect.Driver = (*txDriver)(nil) diff --git a/entc/integration/privacy/privacy_test.go b/entc/integration/privacy/privacy_test.go new file mode 100644 index 000000000..461dea782 --- /dev/null +++ b/entc/integration/privacy/privacy_test.go @@ -0,0 +1,41 @@ +package privacy + +import ( + "context" + "errors" + "testing" + + "github.com/facebookincubator/ent/entc/integration/privacy/ent" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/privacy" + _ "github.com/facebookincubator/ent/entc/integration/privacy/ent/runtime" + "github.com/facebookincubator/ent/entc/integration/privacy/rule" + _ "github.com/mattn/go-sqlite3" + "github.com/stretchr/testify/require" +) + +func TestPrivacyRules(t *testing.T) { + client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") + require.NoError(t, err) + defer client.Close() + ctx := context.Background() + err = client.Schema.Create(ctx) + require.NoError(t, err) + logf := rule.SetMutationLogFunc(t.Logf) + defer rule.SetMutationLogFunc(logf) + + earth, err := client.Planet.Create().SetName("Earth").SetAge(4_540_000_000).Save(ctx) + require.NoError(t, err) + mars := client.Planet.Create().SetName("Mars").SaveX(ctx) + err = earth.Update().AddNeighbors(mars).Exec(ctx) + require.NoError(t, err) + + logf = rule.SetMutationLogFunc(func(string, ...interface{}) { + require.FailNow(t, "hook called on privacy deny") + }) + defer rule.SetMutationLogFunc(logf) + err = client.Planet.Update().Where(planet.ID(earth.ID)).SetAge(4_600_000_000).Exec(ctx) + require.True(t, errors.Is(err, privacy.Deny)) + err = earth.Update().AddNeighbors(earth).Exec(ctx) + require.True(t, errors.Is(err, privacy.Deny)) +} diff --git a/entc/integration/privacy/rule/rule.go b/entc/integration/privacy/rule/rule.go new file mode 100644 index 000000000..952d70295 --- /dev/null +++ b/entc/integration/privacy/rule/rule.go @@ -0,0 +1,68 @@ +package rule + +import ( + "context" + "sync" + + "github.com/facebookincubator/ent/entc/integration/privacy/ent" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/hook" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/privacy" +) + +// DenyUpdateRule is a write rule rule that denies update many operations. +func DenyUpdateRule() privacy.WriteRule { + return privacy.WriteRuleFunc(func(_ context.Context, m ent.Mutation) error { + if m.Op() == ent.OpUpdate { + return privacy.Denyf("ent/privacy: update operation not allowed") + } + return privacy.Skip + }) +} + +// DenyPlanetSelfLinkRule is a write rule rule that prevents rule self link via neighbor edge. +func DenyPlanetSelfLinkRule() privacy.WriteRule { + return privacy.PlanetWriteRuleFunc(func(ctx context.Context, m *ent.PlanetMutation) error { + if !m.Op().Is(ent.OpUpdateOne) { + return privacy.Skip + } + id, exists := m.ID() + if !exists { + return privacy.Denyf("ent/privacy: rule id not provided") + } + for _, neighbor := range m.NeighborsIDs() { + if id == neighbor { + return privacy.Denyf("ent/privacy: planet %d cannot have itself as a neighbor", id) + } + } + return privacy.Skip + }) +} + +var logger = struct { + logf func(string, ...interface{}) + sync.RWMutex +}{ + logf: func(string, ...interface{}) {}, +} + +// SetMutationLogFunc overrides the logging function used by LogPlanetMutationHook. +func SetMutationLogFunc(f func(string, ...interface{})) func(string, ...interface{}) { + logger.Lock() + defer logger.Unlock() + logf := logger.logf + logger.logf = f + return logf +} + +// LogPlanetMutationHook returns a hook logging planet mutations. +func LogPlanetMutationHook() ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return hook.PlanetFunc(func(ctx context.Context, m *ent.PlanetMutation) (ent.Value, error) { + value, err := next.Mutate(ctx, m) + logger.RLock() + defer logger.RUnlock() + logger.logf("planet mutation: type %s, value %v, err %v", m.Op(), value, err) + return value, err + }) + } +} diff --git a/entc/integration/template/ent/client.go b/entc/integration/template/ent/client.go index 03e22a949..34a79fb53 100644 --- a/entc/integration/template/ent/client.go +++ b/entc/integration/template/ent/client.go @@ -40,15 +40,18 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Group: NewGroupClient(c), - Pet: NewPetClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Group = NewGroupClient(c.config) + c.Pet = NewPetClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -76,7 +79,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Group: NewGroupClient(cfg), @@ -96,14 +99,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Group: NewGroupClient(cfg), - Pet: NewPetClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -111,6 +110,14 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Group.Use(hooks...) + c.Pet.Use(hooks...) + c.User.Use(hooks...) +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -121,14 +128,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -138,12 +153,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id int) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -153,7 +171,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id int) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -175,6 +196,11 @@ func (c *GroupClient) GetX(ctx context.Context, id int) *Group { return gr } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -185,14 +211,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -202,12 +236,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id int) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -217,7 +254,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id int) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -253,6 +293,11 @@ func (c *PetClient) QueryOwner(pe *Pet) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -263,14 +308,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -280,12 +333,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -295,7 +351,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -344,3 +403,8 @@ func (c *UserClient) QueryFriends(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/entc/integration/template/ent/config.go b/entc/integration/template/ent/config.go index dd64c4cf6..34dab2204 100644 --- a/entc/integration/template/ent/config.go +++ b/entc/integration/template/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,15 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Group []ent.Hook + Pet []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/entc/integration/template/ent/ent.go b/entc/integration/template/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/entc/integration/template/ent/ent.go +++ b/entc/integration/template/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/entc/integration/template/ent/group/group.go b/entc/integration/template/ent/group/group.go index 60b698a55..24bf69460 100644 --- a/entc/integration/template/ent/group/group.go +++ b/entc/integration/template/ent/group/group.go @@ -10,8 +10,7 @@ const ( // Label holds the string label denoting the group type in the database. Label = "group" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldMaxUsers holds the string denoting the max_users vertex property in the database. + FieldID = "id" // FieldMaxUsers holds the string denoting the max_users vertex property in the database. FieldMaxUsers = "max_users" // Table holds the table name of the group in the database. diff --git a/entc/integration/template/ent/group_create.go b/entc/integration/template/ent/group_create.go index 798c61b6d..a276d6e36 100644 --- a/entc/integration/template/ent/group_create.go +++ b/entc/integration/template/ent/group_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/template/ent/group" @@ -18,21 +19,45 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - max_users *int + mutation *GroupMutation + hooks []Hook } // SetMaxUsers sets the max_users field. func (gc *GroupCreate) SetMaxUsers(i int) *GroupCreate { - gc.max_users = &i + gc.mutation.SetMaxUsers(i) return gc } // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - if gc.max_users == nil { + if _, ok := gc.mutation.MaxUsers(); !ok { return nil, errors.New("ent: missing required field \"max_users\"") } - return gc.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -55,13 +80,13 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, } ) - if value := gc.max_users; value != nil { + if value, ok := gc.mutation.MaxUsers(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) - gr.MaxUsers = *value + gr.MaxUsers = value } if err := sqlgraph.CreateNode(ctx, gc.driver, _spec); err != nil { if cerr, ok := isSQLConstraintError(err); ok { diff --git a/entc/integration/template/ent/group_delete.go b/entc/integration/template/ent/group_delete.go index 8857d0e2c..1ccc22ea7 100644 --- a/entc/integration/template/ent/group_delete.go +++ b/entc/integration/template/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/template/ent/group_update.go b/entc/integration/template/ent/group_update.go index bb069cc3f..676a9f60c 100644 --- a/entc/integration/template/ent/group_update.go +++ b/entc/integration/template/ent/group_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,9 +20,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - max_users *int - addmax_users *int - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -32,24 +33,43 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // SetMaxUsers sets the max_users field. func (gu *GroupUpdate) SetMaxUsers(i int) *GroupUpdate { - gu.max_users = &i - gu.addmax_users = nil + gu.mutation.ResetMaxUsers() + gu.mutation.SetMaxUsers(i) return gu } // AddMaxUsers adds i to max_users. func (gu *GroupUpdate) AddMaxUsers(i int) *GroupUpdate { - if gu.addmax_users == nil { - gu.addmax_users = &i - } else { - *gu.addmax_users += i - } + gu.mutation.AddMaxUsers(i) return gu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - return gu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -92,17 +112,17 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := gu.max_users; value != nil { + if value, ok := gu.mutation.MaxUsers(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } - if value := gu.addmax_users; value != nil { + if value, ok := gu.mutation.AddedMaxUsers(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } @@ -120,31 +140,49 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id int - max_users *int - addmax_users *int + hooks []Hook + mutation *GroupMutation } // SetMaxUsers sets the max_users field. func (guo *GroupUpdateOne) SetMaxUsers(i int) *GroupUpdateOne { - guo.max_users = &i - guo.addmax_users = nil + guo.mutation.ResetMaxUsers() + guo.mutation.SetMaxUsers(i) return guo } // AddMaxUsers adds i to max_users. func (guo *GroupUpdateOne) AddMaxUsers(i int) *GroupUpdateOne { - if guo.addmax_users == nil { - guo.addmax_users = &i - } else { - *guo.addmax_users += i - } + guo.mutation.AddMaxUsers(i) return guo } // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - return guo.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -175,23 +213,27 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeInt, Column: group.FieldID, }, }, } - if value := guo.max_users; value != nil { + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := guo.mutation.MaxUsers(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } - if value := guo.addmax_users; value != nil { + if value, ok := guo.mutation.AddedMaxUsers(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: group.FieldMaxUsers, }) } diff --git a/entc/integration/template/ent/hook/hook.go b/entc/integration/template/ent/hook/hook.go new file mode 100644 index 000000000..a74426b47 --- /dev/null +++ b/entc/integration/template/ent/hook/hook.go @@ -0,0 +1,87 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/template/ent" +) + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/entc/integration/template/ent/mutation.go b/entc/integration/template/ent/mutation.go new file mode 100644 index 000000000..c40af7e27 --- /dev/null +++ b/entc/integration/template/ent/mutation.go @@ -0,0 +1,1042 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "time" + + "github.com/facebookincubator/ent/entc/integration/ent" + "github.com/facebookincubator/ent/entc/integration/template/ent/group" + "github.com/facebookincubator/ent/entc/integration/template/ent/pet" + "github.com/facebookincubator/ent/entc/integration/template/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeGroup = "Group" + TypePet = "Pet" + TypeUser = "User" +) + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *int + max_users *int + addmax_users *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetMaxUsers sets the max_users field. +func (m *GroupMutation) SetMaxUsers(i int) { + m.max_users = &i + m.addmax_users = nil +} + +// MaxUsers returns the max_users value in the mutation. +func (m *GroupMutation) MaxUsers() (r int, exists bool) { + v := m.max_users + if v == nil { + return + } + return *v, true +} + +// AddMaxUsers adds i to max_users. +func (m *GroupMutation) AddMaxUsers(i int) { + if m.addmax_users != nil { + *m.addmax_users += i + } else { + m.addmax_users = &i + } +} + +// AddedMaxUsers returns the value that was added to the max_users field in this mutation. +func (m *GroupMutation) AddedMaxUsers() (r int, exists bool) { + v := m.addmax_users + if v == nil { + return + } + return *v, true +} + +// ResetMaxUsers reset all changes of the max_users field. +func (m *GroupMutation) ResetMaxUsers() { + m.max_users = nil + m.addmax_users = nil +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.max_users != nil { + fields = append(fields, group.FieldMaxUsers) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + case group.FieldMaxUsers: + return m.MaxUsers() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + case group.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMaxUsers(v) + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + var fields []string + if m.addmax_users != nil { + fields = append(fields, group.FieldMaxUsers) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case group.FieldMaxUsers: + return m.AddedMaxUsers() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + case group.FieldMaxUsers: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMaxUsers(v) + return nil + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + case group.FieldMaxUsers: + m.ResetMaxUsers() + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + licensed_at *time.Time + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *PetMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *PetMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *PetMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *PetMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *PetMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetLicensedAt sets the licensed_at field. +func (m *PetMutation) SetLicensedAt(t time.Time) { + m.licensed_at = &t +} + +// LicensedAt returns the licensed_at value in the mutation. +func (m *PetMutation) LicensedAt() (r time.Time, exists bool) { + v := m.licensed_at + if v == nil { + return + } + return *v, true +} + +// ClearLicensedAt clears the value of licensed_at. +func (m *PetMutation) ClearLicensedAt() { + m.licensed_at = nil + m.clearedFields[pet.FieldLicensedAt] = true +} + +// LicensedAtCleared returns if the field licensed_at was cleared in this mutation. +func (m *PetMutation) LicensedAtCleared() bool { + return m.clearedFields[pet.FieldLicensedAt] +} + +// ResetLicensedAt reset all changes of the licensed_at field. +func (m *PetMutation) ResetLicensedAt() { + m.licensed_at = nil + delete(m.clearedFields, pet.FieldLicensedAt) +} + +// SetOwnerID sets the owner edge to User by id. +func (m *PetMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *PetMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *PetMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *PetMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *PetMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *PetMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, pet.FieldAge) + } + if m.licensed_at != nil { + fields = append(fields, pet.FieldLicensedAt) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + case pet.FieldAge: + return m.Age() + case pet.FieldLicensedAt: + return m.LicensedAt() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + case pet.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case pet.FieldLicensedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLicensedAt(v) + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, pet.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case pet.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + case pet.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + var fields []string + if m.clearedFields[pet.FieldLicensedAt] { + fields = append(fields, pet.FieldLicensedAt) + } + return fields +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + switch name { + case pet.FieldLicensedAt: + m.ClearLicensedAt() + return nil + } + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + case pet.FieldAge: + m.ResetAge() + return nil + case pet.FieldLicensedAt: + m.ResetLicensedAt() + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + case pet.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + case pet.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + pets map[int]struct{} + removedpets map[int]struct{} + friends map[int]struct{} + removedfriends map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddPetIDs adds the pets edge to Pet by ids. +func (m *UserMutation) AddPetIDs(ids ...int) { + if m.pets == nil { + m.pets = make(map[int]struct{}) + } + for i := range ids { + m.pets[ids[i]] = struct{}{} + } +} + +// RemovePetIDs removes the pets edge to Pet by ids. +func (m *UserMutation) RemovePetIDs(ids ...int) { + if m.removedpets == nil { + m.removedpets = make(map[int]struct{}) + } + for i := range ids { + m.removedpets[ids[i]] = struct{}{} + } +} + +// RemovedPets returns the removed ids of pets. +func (m *UserMutation) RemovedPetsIDs() (ids []int) { + for id := range m.removedpets { + ids = append(ids, id) + } + return +} + +// PetsIDs returns the pets ids in the mutation. +func (m *UserMutation) PetsIDs() (ids []int) { + for id := range m.pets { + ids = append(ids, id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.removedpets = nil +} + +// AddFriendIDs adds the friends edge to User by ids. +func (m *UserMutation) AddFriendIDs(ids ...int) { + if m.friends == nil { + m.friends = make(map[int]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (m *UserMutation) RemoveFriendIDs(ids ...int) { + if m.removedfriends == nil { + m.removedfriends = make(map[int]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *UserMutation) RemovedFriendsIDs() (ids []int) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *UserMutation) FriendsIDs() (ids []int) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *UserMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + if m.friends != nil { + edges = append(edges, user.EdgeFriends) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.pets)) + for id := range m.pets { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedpets != nil { + edges = append(edges, user.EdgePets) + } + if m.removedfriends != nil { + edges = append(edges, user.EdgeFriends) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.removedpets)) + for id := range m.removedpets { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgePets: + m.ResetPets() + return nil + case user.EdgeFriends: + m.ResetFriends() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/entc/integration/template/ent/pet/pet.go b/entc/integration/template/ent/pet/pet.go index c9916043c..522ea11a7 100644 --- a/entc/integration/template/ent/pet/pet.go +++ b/entc/integration/template/ent/pet/pet.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the pet type in the database. Label = "pet" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldLicensedAt holds the string denoting the licensed_at vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldLicensedAt holds the string denoting the licensed_at vertex property in the database. FieldLicensedAt = "licensed_at" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the pet in the database. Table = "pets" // OwnerTable is the table the holds the owner relation/edge. diff --git a/entc/integration/template/ent/pet_create.go b/entc/integration/template/ent/pet_create.go index c1d7d3bb0..8bca0fb25 100644 --- a/entc/integration/template/ent/pet_create.go +++ b/entc/integration/template/ent/pet_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "time" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,20 +21,19 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - age *int - licensed_at *time.Time - owner map[int]struct{} + mutation *PetMutation + hooks []Hook } // SetAge sets the age field. func (pc *PetCreate) SetAge(i int) *PetCreate { - pc.age = &i + pc.mutation.SetAge(i) return pc } // SetLicensedAt sets the licensed_at field. func (pc *PetCreate) SetLicensedAt(t time.Time) *PetCreate { - pc.licensed_at = &t + pc.mutation.SetLicensedAt(t) return pc } @@ -47,10 +47,7 @@ func (pc *PetCreate) SetNillableLicensedAt(t *time.Time) *PetCreate { // SetOwnerID sets the owner edge to User by id. func (pc *PetCreate) SetOwnerID(id int) *PetCreate { - if pc.owner == nil { - pc.owner = make(map[int]struct{}) - } - pc.owner[id] = struct{}{} + pc.mutation.SetOwnerID(id) return pc } @@ -69,13 +66,33 @@ func (pc *PetCreate) SetOwner(u *User) *PetCreate { // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - if pc.age == nil { + if _, ok := pc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if len(pc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } } - return pc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -98,23 +115,23 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, } ) - if value := pc.age; value != nil { + if value, ok := pc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: pet.FieldAge, }) - pe.Age = *value + pe.Age = value } - if value := pc.licensed_at; value != nil { + if value, ok := pc.mutation.LicensedAt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: pet.FieldLicensedAt, }) - pe.LicensedAt = value + pe.LicensedAt = &value } - if nodes := pc.owner; len(nodes) > 0 { + if nodes := pc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -128,7 +145,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/template/ent/pet_delete.go b/entc/integration/template/ent/pet_delete.go index 78879aa23..55bc3da21 100644 --- a/entc/integration/template/ent/pet_delete.go +++ b/entc/integration/template/ent/pet_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/template/ent/pet_update.go b/entc/integration/template/ent/pet_update.go index 55218c01d..b519637ce 100644 --- a/entc/integration/template/ent/pet_update.go +++ b/entc/integration/template/ent/pet_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "time" "github.com/facebookincubator/ent/dialect/sql" @@ -22,13 +22,9 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - age *int - addage *int - licensed_at *time.Time - clearlicensed_at bool - owner map[int]struct{} - clearedOwner bool - predicates []predicate.Pet + hooks []Hook + mutation *PetMutation + predicates []predicate.Pet } // Where adds a new predicate for the builder. @@ -39,24 +35,20 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // SetAge sets the age field. func (pu *PetUpdate) SetAge(i int) *PetUpdate { - pu.age = &i - pu.addage = nil + pu.mutation.ResetAge() + pu.mutation.SetAge(i) return pu } // AddAge adds i to age. func (pu *PetUpdate) AddAge(i int) *PetUpdate { - if pu.addage == nil { - pu.addage = &i - } else { - *pu.addage += i - } + pu.mutation.AddAge(i) return pu } // SetLicensedAt sets the licensed_at field. func (pu *PetUpdate) SetLicensedAt(t time.Time) *PetUpdate { - pu.licensed_at = &t + pu.mutation.SetLicensedAt(t) return pu } @@ -70,17 +62,13 @@ func (pu *PetUpdate) SetNillableLicensedAt(t *time.Time) *PetUpdate { // ClearLicensedAt clears the value of licensed_at. func (pu *PetUpdate) ClearLicensedAt() *PetUpdate { - pu.licensed_at = nil - pu.clearlicensed_at = true + pu.mutation.ClearLicensedAt() return pu } // SetOwnerID sets the owner edge to User by id. func (pu *PetUpdate) SetOwnerID(id int) *PetUpdate { - if pu.owner == nil { - pu.owner = make(map[int]struct{}) - } - pu.owner[id] = struct{}{} + pu.mutation.SetOwnerID(id) return pu } @@ -99,16 +87,37 @@ func (pu *PetUpdate) SetOwner(u *User) *PetUpdate { // ClearOwner clears the owner edge to User. func (pu *PetUpdate) ClearOwner() *PetUpdate { - pu.clearedOwner = true + pu.mutation.ClearOwner() return pu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - if len(pu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } } - return pu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -151,34 +160,34 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := pu.age; value != nil { + if value, ok := pu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: pet.FieldAge, }) } - if value := pu.addage; value != nil { + if value, ok := pu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: pet.FieldAge, }) } - if value := pu.licensed_at; value != nil { + if value, ok := pu.mutation.LicensedAt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: pet.FieldLicensedAt, }) } - if pu.clearlicensed_at { + if pu.mutation.LicensedAtCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeTime, Column: pet.FieldLicensedAt, }) } - if pu.clearedOwner { + if pu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -194,7 +203,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.owner; len(nodes) > 0 { + if nodes := pu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -208,7 +217,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -227,35 +236,26 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id int - age *int - addage *int - licensed_at *time.Time - clearlicensed_at bool - owner map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *PetMutation } // SetAge sets the age field. func (puo *PetUpdateOne) SetAge(i int) *PetUpdateOne { - puo.age = &i - puo.addage = nil + puo.mutation.ResetAge() + puo.mutation.SetAge(i) return puo } // AddAge adds i to age. func (puo *PetUpdateOne) AddAge(i int) *PetUpdateOne { - if puo.addage == nil { - puo.addage = &i - } else { - *puo.addage += i - } + puo.mutation.AddAge(i) return puo } // SetLicensedAt sets the licensed_at field. func (puo *PetUpdateOne) SetLicensedAt(t time.Time) *PetUpdateOne { - puo.licensed_at = &t + puo.mutation.SetLicensedAt(t) return puo } @@ -269,17 +269,13 @@ func (puo *PetUpdateOne) SetNillableLicensedAt(t *time.Time) *PetUpdateOne { // ClearLicensedAt clears the value of licensed_at. func (puo *PetUpdateOne) ClearLicensedAt() *PetUpdateOne { - puo.licensed_at = nil - puo.clearlicensed_at = true + puo.mutation.ClearLicensedAt() return puo } // SetOwnerID sets the owner edge to User by id. func (puo *PetUpdateOne) SetOwnerID(id int) *PetUpdateOne { - if puo.owner == nil { - puo.owner = make(map[int]struct{}) - } - puo.owner[id] = struct{}{} + puo.mutation.SetOwnerID(id) return puo } @@ -298,16 +294,37 @@ func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne { // ClearOwner clears the owner edge to User. func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne { - puo.clearedOwner = true + puo.mutation.ClearOwner() return puo } // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - if len(puo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } } - return puo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -338,40 +355,44 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { Table: pet.Table, Columns: pet.Columns, ID: &sqlgraph.FieldSpec{ - Value: puo.id, Type: field.TypeInt, Column: pet.FieldID, }, }, } - if value := puo.age; value != nil { + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := puo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: pet.FieldAge, }) } - if value := puo.addage; value != nil { + if value, ok := puo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: pet.FieldAge, }) } - if value := puo.licensed_at; value != nil { + if value, ok := puo.mutation.LicensedAt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: pet.FieldLicensedAt, }) } - if puo.clearlicensed_at { + if puo.mutation.LicensedAtCleared() { _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ Type: field.TypeTime, Column: pet.FieldLicensedAt, }) } - if puo.clearedOwner { + if puo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -387,7 +408,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.owner; len(nodes) > 0 { + if nodes := puo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -401,7 +422,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/integration/template/ent/privacy/privacy.go b/entc/integration/template/ent/privacy/privacy.go new file mode 100644 index 000000000..ea20c39f6 --- /dev/null +++ b/entc/integration/template/ent/privacy/privacy.go @@ -0,0 +1,219 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/entc/integration/template/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/entc/integration/template/ent/runtime.go b/entc/integration/template/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/entc/integration/template/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/entc/integration/template/ent/runtime/runtime.go b/entc/integration/template/ent/runtime/runtime.go new file mode 100644 index 000000000..685bbfb20 --- /dev/null +++ b/entc/integration/template/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/entc/integration/template/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/entc/integration/template/ent/tx.go b/entc/integration/template/ent/tx.go index 5f902de05..52cc9304d 100644 --- a/entc/integration/template/ent/tx.go +++ b/entc/integration/template/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/entc/integration/template/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -36,13 +35,15 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Group: NewGroupClient(tx.config), - Pet: NewPetClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Group = NewGroupClient(tx.config) + tx.Pet = NewPetClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/entc/integration/template/ent/user/user.go b/entc/integration/template/ent/user/user.go index d5878817c..6d1865b01 100644 --- a/entc/integration/template/ent/user/user.go +++ b/entc/integration/template/ent/user/user.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // Table holds the table name of the user in the database. Table = "users" // PetsTable is the table the holds the pets relation/edge. diff --git a/entc/integration/template/ent/user_create.go b/entc/integration/template/ent/user_create.go index 1dd03be1d..54fa53908 100644 --- a/entc/integration/template/ent/user_create.go +++ b/entc/integration/template/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/entc/integration/template/ent/pet" @@ -19,25 +20,19 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - name *string - pets map[int]struct{} - friends map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // AddPetIDs adds the pets edge to Pet by ids. func (uc *UserCreate) AddPetIDs(ids ...int) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[int]struct{}) - } - for i := range ids { - uc.pets[ids[i]] = struct{}{} - } + uc.mutation.AddPetIDs(ids...) return uc } @@ -52,12 +47,7 @@ func (uc *UserCreate) AddPets(p ...*Pet) *UserCreate { // AddFriendIDs adds the friends edge to User by ids. func (uc *UserCreate) AddFriendIDs(ids ...int) *UserCreate { - if uc.friends == nil { - uc.friends = make(map[int]struct{}) - } - for i := range ids { - uc.friends[ids[i]] = struct{}{} - } + uc.mutation.AddFriendIDs(ids...) return uc } @@ -72,10 +62,33 @@ func (uc *UserCreate) AddFriends(u ...*User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -98,15 +111,15 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.pets; len(nodes) > 0 { + if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -120,12 +133,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.friends; len(nodes) > 0 { + if nodes := uc.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -139,7 +152,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/entc/integration/template/ent/user_delete.go b/entc/integration/template/ent/user_delete.go index 93288bcda..0b44ed268 100644 --- a/entc/integration/template/ent/user_delete.go +++ b/entc/integration/template/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/entc/integration/template/ent/user_update.go b/entc/integration/template/ent/user_update.go index ccd4a0e41..29fc6ce75 100644 --- a/entc/integration/template/ent/user_update.go +++ b/entc/integration/template/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,12 +21,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - name *string - pets map[int]struct{} - friends map[int]struct{} - removedPets map[int]struct{} - removedFriends map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -36,18 +34,13 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // AddPetIDs adds the pets edge to Pet by ids. func (uu *UserUpdate) AddPetIDs(ids ...int) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[int]struct{}) - } - for i := range ids { - uu.pets[ids[i]] = struct{}{} - } + uu.mutation.AddPetIDs(ids...) return uu } @@ -62,12 +55,7 @@ func (uu *UserUpdate) AddPets(p ...*Pet) *UserUpdate { // AddFriendIDs adds the friends edge to User by ids. func (uu *UserUpdate) AddFriendIDs(ids ...int) *UserUpdate { - if uu.friends == nil { - uu.friends = make(map[int]struct{}) - } - for i := range ids { - uu.friends[ids[i]] = struct{}{} - } + uu.mutation.AddFriendIDs(ids...) return uu } @@ -82,12 +70,7 @@ func (uu *UserUpdate) AddFriends(u ...*User) *UserUpdate { // RemovePetIDs removes the pets edge to Pet by ids. func (uu *UserUpdate) RemovePetIDs(ids ...int) *UserUpdate { - if uu.removedPets == nil { - uu.removedPets = make(map[int]struct{}) - } - for i := range ids { - uu.removedPets[ids[i]] = struct{}{} - } + uu.mutation.RemovePetIDs(ids...) return uu } @@ -102,12 +85,7 @@ func (uu *UserUpdate) RemovePets(p ...*Pet) *UserUpdate { // RemoveFriendIDs removes the friends edge to User by ids. func (uu *UserUpdate) RemoveFriendIDs(ids ...int) *UserUpdate { - if uu.removedFriends == nil { - uu.removedFriends = make(map[int]struct{}) - } - for i := range ids { - uu.removedFriends[ids[i]] = struct{}{} - } + uu.mutation.RemoveFriendIDs(ids...) return uu } @@ -122,7 +100,31 @@ func (uu *UserUpdate) RemoveFriends(u ...*User) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -165,14 +167,14 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedPets; len(nodes) > 0 { + if nodes := uu.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -186,12 +188,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.pets; len(nodes) > 0 { + if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -205,12 +207,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFriends; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -224,12 +226,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.friends; len(nodes) > 0 { + if nodes := uu.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -243,7 +245,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -262,28 +264,19 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - name *string - pets map[int]struct{} - friends map[int]struct{} - removedPets map[int]struct{} - removedFriends map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // AddPetIDs adds the pets edge to Pet by ids. func (uuo *UserUpdateOne) AddPetIDs(ids ...int) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[int]struct{}) - } - for i := range ids { - uuo.pets[ids[i]] = struct{}{} - } + uuo.mutation.AddPetIDs(ids...) return uuo } @@ -298,12 +291,7 @@ func (uuo *UserUpdateOne) AddPets(p ...*Pet) *UserUpdateOne { // AddFriendIDs adds the friends edge to User by ids. func (uuo *UserUpdateOne) AddFriendIDs(ids ...int) *UserUpdateOne { - if uuo.friends == nil { - uuo.friends = make(map[int]struct{}) - } - for i := range ids { - uuo.friends[ids[i]] = struct{}{} - } + uuo.mutation.AddFriendIDs(ids...) return uuo } @@ -318,12 +306,7 @@ func (uuo *UserUpdateOne) AddFriends(u ...*User) *UserUpdateOne { // RemovePetIDs removes the pets edge to Pet by ids. func (uuo *UserUpdateOne) RemovePetIDs(ids ...int) *UserUpdateOne { - if uuo.removedPets == nil { - uuo.removedPets = make(map[int]struct{}) - } - for i := range ids { - uuo.removedPets[ids[i]] = struct{}{} - } + uuo.mutation.RemovePetIDs(ids...) return uuo } @@ -338,12 +321,7 @@ func (uuo *UserUpdateOne) RemovePets(p ...*Pet) *UserUpdateOne { // RemoveFriendIDs removes the friends edge to User by ids. func (uuo *UserUpdateOne) RemoveFriendIDs(ids ...int) *UserUpdateOne { - if uuo.removedFriends == nil { - uuo.removedFriends = make(map[int]struct{}) - } - for i := range ids { - uuo.removedFriends[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFriendIDs(ids...) return uuo } @@ -358,7 +336,31 @@ func (uuo *UserUpdateOne) RemoveFriends(u ...*User) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -389,20 +391,24 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.name; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedPets; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -416,12 +422,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.pets; len(nodes) > 0 { + if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -435,12 +441,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFriends; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -454,12 +460,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.friends; len(nodes) > 0 { + if nodes := uuo.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -473,7 +479,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/entc/load/internal/bindata.go b/entc/load/internal/bindata.go index 0786527bf..9bccc1840 100644 --- a/entc/load/internal/bindata.go +++ b/entc/load/internal/bindata.go @@ -78,7 +78,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templateMainTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x51\x5d\x6b\xdb\x30\x14\x7d\xb6\x7e\xc5\x99\xe9\xa8\x5d\x52\xa5\xed\xdb\x06\x79\x28\x6d\x06\x19\x5b\x3b\x48\x61\x0f\x5d\x29\x8a\x7d\x9d\x88\x3a\x92\x77\xa5\x94\x05\xa1\xff\x3e\x24\x27\x61\x7b\xb2\xa5\x73\xee\xf9\xd0\x0d\x61\x7a\x21\xee\xec\xb0\x67\xbd\xde\x78\xdc\x5c\x5d\x7f\xba\x1c\x98\x1c\x19\x8f\x2f\xaa\xa1\x95\xb5\x6f\x58\x98\x46\xe2\xb6\xef\x91\x49\x0e\x09\xe7\x77\x6a\xa5\x78\xda\x68\x07\x67\x77\xdc\x10\x1a\xdb\x12\xb4\x43\xaf\x1b\x32\x8e\x5a\xec\x4c\x4b\x0c\xbf\x21\xdc\x0e\xaa\xd9\x10\x6e\xe4\xd5\x11\x45\x67\x77\xa6\x15\xda\x64\xfc\xdb\xe2\x6e\xfe\xb0\x9c\xa3\xd3\x3d\xe1\x70\xc7\xd6\x7a\xb4\x9a\xa9\xf1\x96\xf7\xb0\x1d\xfc\x3f\x66\x9e\x89\xa4\xb8\x98\xc6\x28\x44\x08\x68\xa9\xd3\x86\x50\x6e\x95\x36\x25\x62\x14\xd3\x29\xee\x52\x9e\x35\x19\x62\xe5\xa9\xc5\x6a\x8f\x73\x32\xbe\x39\x5d\x9d\x4b\xdc\x3f\xe2\xe1\xf1\x09\xf3\xfb\xc5\x93\x14\x83\x6a\xde\xd4\x9a\x90\x34\x84\xd0\xdb\xc1\xb2\x47\x25\x8a\xd2\xba\x52\x14\xe5\x6a\xef\x29\xfd\x84\x00\x4f\xdb\xa1\x57\x9e\x50\x8e\x2c\x97\x2d\x33\x34\xb0\x36\xbe\x43\xf9\xf1\x77\x09\xf9\xe3\xa0\x18\xa3\xa8\x73\xcc\xb3\x95\x72\x84\xcf\x33\xe4\xef\x11\x4f\xb3\xef\x8a\xe1\x9a\x0d\x6d\x95\xc3\x0c\xcf\x2f\x64\xbc\x5c\x18\x4f\xdc\xa9\x86\x42\x96\x66\x65\xd6\x84\xb3\xd7\x09\xce\x8c\xda\x66\x19\xf9\xa0\xb6\xe4\x92\x7e\x51\x84\x70\x79\xd0\x8f\x51\xa6\xc3\x29\x8a\x0b\xb1\x3c\xcc\xc4\x38\xc9\x5a\x64\x5a\x5c\xc6\x28\xa2\x10\xdd\xce\x34\xb9\x73\x55\x23\x88\x22\x05\xe9\xb5\x21\x87\xe7\x97\xe7\x97\x54\x5a\x14\x9d\x65\xbc\x4e\x0e\xf9\x92\xef\x18\xe5\x98\x37\x88\xa2\x58\x4d\x40\xcc\x09\xfb\xae\xd8\x6d\x54\xbf\xcc\x60\x35\x72\x6a\x51\x14\xba\xcb\x8c\x0f\x33\x18\xdd\xe7\x99\xa2\x53\xba\xaf\x88\x39\xc1\xa9\xc2\xe8\x3b\x83\x1a\x06\x32\x6d\x95\x8f\x13\xac\x6a\x91\x50\xeb\xe4\xd2\xb7\x76\xe7\xe5\x4f\xd6\x9e\xaa\xbc\x0f\xf9\xd5\x6a\x73\x24\x8e\x71\xab\xf2\x97\x29\xeb\xba\x3e\x75\x3b\xba\x24\x7b\xcb\xb9\xe4\xa8\x45\xcc\xa3\xd6\xd2\xb3\x36\xeb\xc4\x91\xf3\xc4\xa9\xea\x3a\x73\xe6\x7f\xb4\xaf\xae\xb3\xd2\x7f\x5b\x1f\x4b\x8d\x4b\x3f\x3c\x66\x8c\xe2\x6f\x00\x00\x00\xff\xff\xe4\x6e\x0c\x4d\x4b\x03\x00\x00") +var _templateMainTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x51\x5f\x6b\xdb\x3e\x14\x7d\xb6\x3e\xc5\xf9\x99\xfe\xa8\xdd\xa5\x4a\xdb\xb7\x0d\xf2\x50\xda\x0c\x32\xb6\x76\x90\xc2\x1e\xba\x52\x14\xfb\x3a\x11\x75\x24\xef\x4a\x29\x0b\x42\xdf\x7d\x48\x4e\xc2\xf6\x64\x4b\xe7\xdc\xf3\x47\x37\x84\xe9\x85\xb8\xb3\xc3\x9e\xf5\x7a\xe3\x71\x73\x75\xfd\xf1\x72\x60\x72\x64\x3c\x3e\xab\x86\x56\xd6\xbe\x61\x61\x1a\x89\xdb\xbe\x47\x26\x39\x24\x9c\xdf\xa9\x95\xe2\x69\xa3\x1d\x9c\xdd\x71\x43\x68\x6c\x4b\xd0\x0e\xbd\x6e\xc8\x38\x6a\xb1\x33\x2d\x31\xfc\x86\x70\x3b\xa8\x66\x43\xb8\x91\x57\x47\x14\x9d\xdd\x99\x56\x68\x93\xf1\xaf\x8b\xbb\xf9\xc3\x72\x8e\x4e\xf7\x84\xc3\x1d\x5b\xeb\xd1\x6a\xa6\xc6\x5b\xde\xc3\x76\xf0\x7f\x99\x79\x26\x92\xe2\x62\x1a\xa3\x10\x21\xa0\xa5\x4e\x1b\x42\xb9\x55\xda\x94\x88\x51\x4c\xa7\xb8\x4b\x79\xd6\x64\x88\x95\xa7\x16\xab\x3d\xce\xc9\xf8\xe6\x74\x75\x2e\x71\xff\x88\x87\xc7\x27\xcc\xef\x17\x4f\x52\x0c\xaa\x79\x53\x6b\x42\xd2\x10\x42\x6f\x07\xcb\x1e\x95\x28\x4a\xeb\x4a\x51\x94\xab\xbd\xa7\xf4\x13\x02\x3c\x6d\x87\x5e\x79\x42\x39\xb2\x5c\xb6\xcc\xd0\xc0\xda\xf8\x0e\xe5\xff\xbf\x4a\xc8\xef\x07\xc5\x18\x45\x9d\x63\x9e\xad\x94\x23\x7c\x9a\x21\x7f\x8f\x78\x9a\x7d\x57\x0c\xd7\x6c\x68\xab\x1c\x66\x78\x7e\x21\xe3\xe5\xc2\x78\xe2\x4e\x35\x14\xb2\x34\x2b\xb3\x26\x9c\xbd\x4e\x70\x66\xd4\x36\xcb\xc8\x07\xb5\x25\x97\xf4\x8b\x22\x84\xcb\x83\x7e\x8c\x32\x1d\x4e\x51\x5c\x88\xe5\x61\x26\xc6\x49\xd6\x22\xd3\xe2\x32\x46\x11\x85\xe8\x76\xa6\xc9\x9d\xab\x1a\x41\x14\x29\x48\xaf\x0d\x39\x3c\xbf\x3c\xbf\xa4\xd2\xa2\xe8\x2c\xe3\x75\x72\xc8\x97\x7c\xc7\x28\xc7\xbc\x41\x14\xc5\x6a\x02\x62\x4e\xd8\x37\xc5\x6e\xa3\xfa\x65\x06\xab\x91\x53\x8b\xa2\xd0\x5d\x66\xfc\x37\x83\xd1\x7d\x9e\x29\x3a\xa5\xfb\x8a\x98\x13\x9c\x2a\x8c\xbe\x33\xa8\x61\x20\xd3\x56\xf9\x38\xc1\xaa\x16\x09\xb5\x4e\x2e\x7d\x6b\x77\x5e\xfe\x60\xed\xa9\xca\xfb\x90\x5f\xac\x36\x47\xe2\x18\xb7\x2a\x7f\x9a\xb2\xae\xeb\x53\xb7\xa3\x4b\xb2\xb7\x9c\x4b\x8e\x5a\xc4\x3c\x6a\x2d\x3d\x6b\xb3\x4e\x1c\x39\x4f\x9c\xaa\xfe\x90\x45\x32\x71\xfe\x5b\xfb\xea\x3a\xcb\xfd\xb3\xfa\xb1\xd9\xb8\xf9\xc3\x8b\xc6\x28\xfe\x04\x00\x00\xff\xff\x95\x06\x0f\xa4\x50\x03\x00\x00") func templateMainTmplBytes() ([]byte, error) { return bindataRead( @@ -93,12 +93,12 @@ func templateMainTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/main.tmpl", size: 843, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/main.tmpl", size: 848, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _schemaGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\xdd\x8f\xd3\x48\x12\x7f\x8e\xff\x8a\x22\x12\xa3\x18\x65\x1d\x76\x75\x3a\xe9\x82\xf2\xb0\x82\x41\xca\xed\x31\xac\x16\xd8\x17\x84\x58\x8f\x5d\xce\x34\xd8\x6d\xd3\xdd\x09\x93\x9d\x9d\xff\xfd\x54\x55\xdd\xfe\x88\x33\x61\x81\x1d\x5e\x26\xae\xaf\xae\xfa\xd5\x57\xdb\x2c\x16\xf0\xb4\x6e\xf6\x46\x6d\xae\x1c\xfc\xf4\xf8\xc7\xff\xfc\xd0\x18\xb4\xa8\x1d\x3c\x4f\x33\xbc\xac\xeb\x8f\xb0\xd6\x59\x02\x3f\x97\x25\xb0\x90\x05\xe2\x9b\x1d\xe6\x49\xb4\x58\xc0\xeb\x2b\x65\xc1\xd6\x5b\x93\x21\x64\x75\x8e\xa0\x2c\x94\x2a\x43\x6d\x31\x87\xad\xce\xd1\x80\xbb\x42\xf8\xb9\x49\xb3\x2b\x84\x9f\x92\xc7\x81\x0b\x45\xbd\xd5\x39\x99\x50\x9a\x45\xfe\xb7\x7e\x7a\x7e\xf1\xea\x1c\x0a\x55\x62\xa0\x99\xba\x76\x90\x2b\x83\x99\xab\xcd\x1e\xea\x02\x5c\xef\x3c\x67\x10\x93\x28\x6a\xd2\xec\x63\xba\x41\x28\xeb\x34\x8f\x22\x55\x35\xb5\x71\x30\x8b\x26\x53\xd4\x59\x9d\x2b\xbd\x59\x7c\xb0\xb5\x9e\x46\x93\x69\x51\x39\xfa\x63\xb0\x28\x31\x73\xd3\x28\x9a\x4c\x37\xca\x5d\x6d\x2f\x93\xac\xae\x16\x85\x0f\x58\xe9\x6c\x7b\x99\xba\xda\x2c\x50\xb3\xfc\x97\x64\x16\x36\xbb\xc2\x2a\x5d\x60\xbe\xc1\xaf\x91\x2f\x14\x96\xf9\x34\x8a\x23\x42\xe1\x15\xd3\xc0\xa0\xc7\xdf\x42\xaa\x01\xb5\x4b\x3c\xc3\x5d\xa5\x0e\x3e\xa7\x96\xc3\xc4\x1c\x0a\x53\x57\x90\x42\x56\x57\x4d\xa9\x08\x6b\x8b\x06\x3c\x14\x49\xe4\xf6\x0d\x06\x93\xd6\x99\x6d\xe6\xe0\x26\x9a\x5c\xa4\x15\x02\x00\x51\x94\xde\xd0\x2f\xf8\x83\xb0\x59\x4e\x75\x5a\xe1\xbc\xae\x94\xc3\xaa\x71\xfb\xe9\x1f\xd1\xe4\x69\xad\x0b\xb5\x01\x76\xc1\xff\xf6\xb2\x19\x3f\x0d\xa5\xcf\xf3\x0d\x5a\x00\x78\xfb\xee\x11\xfd\xec\x59\x26\x50\xec\x50\xf8\x39\xc5\x6d\x59\x98\x7f\x76\xc2\x8c\xc8\x81\xf4\x5a\xe7\x78\x8d\x96\xa4\xf9\x67\x27\xad\x84\x33\x10\xbf\x65\x30\x7f\xad\xad\x72\xaa\xd6\x90\xa3\xcd\x8c\xba\x44\x0b\x29\xb0\x71\x68\x02\xcb\x97\x98\xe4\xc2\x23\xd6\xea\x75\x98\x85\x33\x01\x40\x69\x07\xb0\x58\x78\x43\x7c\x7a\xb0\x22\xa4\x52\x59\x97\x44\x93\x17\xea\x1a\xf3\xb5\x26\x95\xcb\xba\x2e\x81\x6b\x3c\x57\x59\xea\xd0\x82\x2a\x7a\x0a\x94\xcf\x8a\xa4\x7f\x50\x5a\x14\x95\x5e\x7b\xbb\x72\x56\x45\xa4\xe1\x59\x42\x92\xb3\x24\x5c\x41\x71\x5c\x3a\x42\xff\x86\xca\x11\xc5\x71\xe1\xc8\xbf\x5e\xf9\x9c\xae\xa1\xb5\x2e\xea\x4e\xec\x11\xc7\x9c\xbc\xde\x37\xc8\x0c\xaf\x46\x07\x0e\xd5\x5e\xa7\x3d\xe3\x77\x9d\xe6\xd2\x83\x12\x7c\xa5\xfe\xec\xf9\xf8\x48\x69\xf7\xef\x7f\x8d\xb4\xac\xfa\xf3\xe0\xb0\x73\xbd\xad\x6c\x2b\xf6\xf6\xdd\xf0\xb8\x50\xc4\x24\x34\xd4\x7b\xa3\xd5\xa7\x6d\x7b\x20\xe7\x19\x46\xc7\x6d\x59\x68\xa8\x78\xa1\xca\x32\xbd\x2c\xf1\xa4\xa2\xf6\x42\x43\xd5\x97\x0d\x15\x67\x5a\x9e\x54\xad\xbd\xd0\x50\xf5\x19\x16\xe9\xb6\x74\xa7\xdd\xcd\x45\xe8\xa8\xe6\xef\x69\x49\xe1\x2a\xed\xd0\xd0\x54\xbb\xb9\x3d\xa2\xf9\x7e\x47\x52\x07\x40\x35\x79\xea\x30\x9c\x7f\x17\x50\x2c\xf4\xfe\xa8\x03\xeb\xaa\xda\xba\x16\xb1\x3b\x0c\xa8\x20\x34\xd4\xfd\x3d\x2d\x55\x4e\x73\x97\x53\xcc\x4d\x35\xd6\xdd\xb5\x42\x07\x15\xe5\x6a\x93\x6e\xf0\x17\xdc\x9f\xa8\x43\x2b\x42\xef\x3f\xe2\x7e\xa8\xdd\xce\x12\xa9\xc7\xe1\x63\xd0\x0e\xd3\xe8\xe0\x60\xd4\x44\xde\x9d\x8c\xd8\x06\xa1\x23\xf3\x8f\x67\xf0\x78\x1e\x30\xf9\x1b\xc6\x01\xeb\x1d\x99\x06\x1e\x92\x3b\xfb\x9f\x5a\xfd\x88\xe0\x89\x8e\x3f\x10\x3c\xec\xf1\xdf\xb0\x90\xc3\x87\x72\x06\x8b\xf7\xe3\xd3\x7f\xc3\xc2\x63\x2f\x2b\xa9\x13\xbe\xa3\x93\x3d\xd0\x27\x7a\x77\xad\x77\x68\x2c\x1e\x8a\x2a\x21\x1f\x1e\xff\x69\xab\x0c\xe6\x07\xb2\xc6\x93\x8f\x64\x4d\x26\xff\x38\x6d\x42\xff\x86\xbc\x89\x62\x97\xb8\xde\xcc\x6a\x8b\xea\x44\xb4\x61\xa9\xf7\xe7\xe2\x97\xb7\xfa\x11\xe9\x63\x6b\xbd\xd7\x5c\x6d\x67\x7d\xa1\xa5\x04\xa5\x0b\xfc\xcc\xf9\xcc\x0c\xf2\x42\x4d\x75\x40\x84\x9c\x12\x58\xf8\x97\xec\xfe\xc6\xd5\x26\x89\x8a\xad\xce\x82\xe6\x0c\x73\x78\x44\x12\xc9\xb3\x56\x22\xf6\x45\x72\x13\x4d\x34\xc2\x72\x05\x67\xf4\x78\x13\x4d\xa8\x34\x97\x82\x01\xe6\xc9\xeb\x74\x33\x27\xda\xbe\xc1\x65\x4b\xa3\x6a\x8e\x26\xdc\x15\x2d\x91\x1e\x88\x28\x88\x2f\x85\x28\x0f\x44\xf6\x75\xb4\x64\xb2\x7f\x20\x7a\xa8\x99\x25\xd1\xc3\x83\x30\x0a\x6f\x9f\x19\x85\xb7\x7f\x1b\x4d\x54\x01\x06\x0b\x72\x59\x38\x4f\xf8\xf1\xc1\x0a\xb4\x2a\x29\x9c\x89\x46\x22\xc3\xaa\x0d\xdf\x60\x11\xb3\xaa\x41\xb7\x35\x1a\x34\x76\xc8\xca\xe2\x1f\x43\x2b\xd7\x95\xd3\xd8\xb2\xee\xac\xc8\xc3\xa2\xef\xa3\x3b\x93\x9b\xde\x1c\xd0\x18\x7a\xbe\x89\x26\x96\x9d\x3e\x63\xfa\xcd\x00\x3f\xfe\x57\x74\x20\xd2\x6d\x61\xc8\x21\xca\x7c\x90\x9c\xc0\xf1\x19\xe2\xad\xbe\xec\x33\x98\x32\x4c\x49\x60\x75\x79\x09\xbb\x79\xd9\xf9\x10\x16\x71\x34\x69\xd7\x6f\xc7\x0d\x14\xe2\xfa\x0d\xb7\xec\xec\x86\x9d\x27\xc9\xe0\xb3\xfb\xbb\x70\xc9\x67\x0f\xb6\x63\x27\xd9\x2e\xbd\x65\x1b\x73\xbb\xe1\xa2\x49\xaf\x7b\x96\x9e\xdd\x51\x88\xdf\xed\x3d\xe6\x97\xa8\x67\x45\x9e\x74\xd4\x98\x8d\x84\x0d\xd2\x9e\xd1\x52\xda\xda\xb2\x05\x83\x0d\xab\xae\xa0\x42\xd9\xa8\x72\x0e\x45\xe5\x92\x73\x4a\x69\x31\x9b\x56\xca\x5a\xea\x63\x1e\x3d\x8a\x94\x8a\xda\xf8\xca\x79\xf8\x69\x3a\x27\x5b\x94\xd2\xb8\xb5\x4d\x37\xb6\xe5\x0a\xf8\xaa\x46\xfe\xd1\x15\x2e\x7e\x22\xf4\x07\x2b\x78\xcc\xc7\xd9\x82\xe9\xb0\x82\x33\x62\xb0\x32\x0d\x4b\xb9\x47\xfb\x1b\x03\xf0\xc5\x03\xb2\x54\xc3\x25\x02\xbf\xf8\x61\x0e\xae\x66\x99\x0d\x6a\x34\x29\xd7\x2a\x69\x3e\xaf\x0d\xe0\x75\x5a\x35\x25\xce\x41\xd7\x8e\x5e\x0d\xb6\x3a\xe3\xe5\x5c\xaa\x8f\x08\x4e\x55\x98\x5c\xd4\x9f\x13\xf6\xf2\x3d\x17\x2d\xf9\x49\xd3\x29\x79\x91\x1a\x7b\x95\x96\xb3\x2e\xbf\xf1\x13\x16\xe8\x21\x64\x8b\x64\x70\x6b\x5a\xf5\xaa\x21\x04\xef\xab\x98\xc7\x07\xe9\x76\x97\xe3\x37\x6f\xd6\xcf\xe0\xec\x6c\x5c\x41\x6c\xdb\xed\x1b\xf2\xc5\xbf\xc3\xb2\xc2\xcb\xa2\xef\x4d\x34\x21\xf3\x6e\xdf\x24\xbf\x28\x9d\xcf\x62\x52\x0e\xd2\xcf\xa9\x55\xff\xfa\x8b\xb9\x17\xdb\x6a\xad\x85\xfd\xb8\x47\x7b\xb9\x75\x42\xfc\x31\x10\x89\xf2\x38\x4e\x5e\xf1\x94\x16\x5e\x70\xbe\xa5\x91\x67\x77\x16\x06\x5e\x37\x98\x39\xa9\x8b\x19\x41\x3d\x8b\xe1\xa1\x8d\xb9\x3c\xb6\x5b\x95\x0f\x93\x38\x9d\x8f\xcc\x53\x4c\xb7\xfd\x91\x65\x8b\x39\x1d\xe3\xe7\x96\x4f\x89\x7f\xdd\x95\xe4\x73\xe2\x7b\xaf\xcf\xed\xbd\x95\x7e\xd5\x90\xc2\x7f\x5f\xbd\xbc\x20\x65\x5e\xab\xbe\x6e\x72\x94\xba\x61\x11\x32\xe0\x95\xeb\xcb\x0f\x14\x80\xfc\xf1\x03\x6f\x70\xe8\xcc\x86\xb3\x69\x5b\xfb\x93\x62\x98\x5d\xc2\xdb\x77\x97\x7b\x87\x52\x42\xbd\xd9\xc7\xa3\x4f\x74\x09\x3a\x79\xc1\x5e\x86\x97\x51\x79\x9c\xc5\xfd\xb5\x42\x6f\x90\x06\x33\x37\x3b\xc8\xbc\xa8\xc4\x31\xb7\x16\xab\x48\x7d\xf9\x9a\xb5\x09\x4d\x70\xd9\xcd\x41\x56\xea\xf5\xc1\xf1\x8e\x46\x63\xd8\x84\x6c\xf8\xd6\x4c\x5a\x20\x5f\x07\x82\x8d\xf6\x8c\x3b\xcc\xf4\xf3\xef\xc1\x79\xf8\x69\x09\x0f\x77\x34\x07\x64\xb2\x93\xba\xcc\x02\x2a\x04\x6a\x33\x2e\xec\x54\x6f\x90\x97\x8c\x95\x5e\x4a\xe4\x1a\xb2\x82\xb4\x69\x50\xe7\x33\x4f\x98\x77\xeb\xbc\xb7\x69\x66\x71\xec\xc7\x8b\xff\x36\xd0\x0f\xc0\x7f\x49\xb8\xcf\x10\x54\x7e\xdd\x05\xe1\x7d\x60\xc3\x9e\xa1\xf2\xeb\x81\xb7\x1c\x60\xf8\xc2\xd1\x0b\x71\x1d\xdc\x3f\xe3\x5f\xdc\x5e\x1c\xb6\x5f\x2f\x64\x47\x60\x20\x8e\xa4\x77\xd9\x72\xe4\x99\x59\xfd\x6d\x47\xac\x6e\xd7\x0d\x76\x08\xb1\x86\x1b\xe4\x76\x70\x47\x18\x8c\x3e\x1b\xfb\xc6\xeb\x4a\x8b\x7f\x5a\x3f\xec\x5d\xed\x0b\xd9\x5f\x18\xfa\x4d\xe1\xbb\x67\x66\xe1\x91\x94\x7f\x0c\xa3\x02\x3d\x6c\x23\xee\x1b\x42\x91\xbf\x7c\x0c\x52\xca\x5f\x4c\xfe\x46\x42\xbf\x3a\x97\x6a\x0e\x55\x2f\x95\xf2\xcd\x85\x0c\xfa\xbb\x6c\xdf\x09\xef\x7c\x75\xed\x67\xef\x81\x0b\x5f\xef\x03\x39\xc1\x5e\x7c\x98\x43\xd1\x39\x21\x47\x8b\x4d\x9a\x80\xde\x85\xee\xea\x35\x6c\x04\x12\x3b\xe2\xcd\x37\xb8\xc3\xfe\xd0\x56\x6b\x5f\x62\x57\x70\x16\x7e\x8b\x51\x2e\x53\x5f\x9c\x1f\xb8\xbc\xc2\x67\x30\x26\x3a\xe3\x8b\xae\xf7\x8d\x6b\x09\x6a\xde\x19\xf7\x45\xdb\x6f\x02\x5f\xc6\x60\x8b\x6e\x01\xdc\x0d\xff\xfd\x14\xc1\x71\xf8\xff\x1e\xfa\xff\x58\x29\xdc\x85\x7c\x80\x91\x65\xbe\x04\x60\xef\xc2\xdf\x6e\xce\x0e\x3e\xf8\x6c\xd2\xc6\xf6\xbf\x88\x7a\x7a\xaa\x73\xa9\xfe\x40\xa8\xd0\x5d\xd5\x39\x7c\x56\xee\x0a\x0c\x66\xf5\x0e\x0d\x75\x3c\x6a\xbb\x35\x08\xba\x86\x26\xd5\x2a\xb3\xa0\x34\x54\x32\x30\x94\xde\xf8\xb6\xef\xa5\xab\xc8\x7b\xdf\x92\xc0\x13\x63\x78\xfb\xae\xfb\x70\x79\x1b\xc3\xcc\x83\xde\x23\x1f\xee\xd2\x1c\x0b\x34\xe0\xaf\x15\x37\x02\xfb\x4e\xae\x48\xec\xdc\x2c\x7e\x02\xbb\x41\x12\xf8\xb6\x36\xc8\xc1\xc3\xd7\x21\x3a\x71\xde\xa7\xa2\xc8\xe7\xb0\xe3\x06\x28\x02\xb6\x84\x9d\xd4\x22\x0d\xef\x90\xce\x3c\x09\x01\xcc\x0f\xd0\x95\xe5\x35\x02\x57\xc8\xdf\x0b\x65\x7f\x23\x8f\xee\x1e\xb2\x42\x05\x38\x12\xbc\x0f\xdc\x06\xd1\x0c\xa0\x13\xd8\xd0\xaf\xee\xa3\xa8\xf5\x95\xc7\xc0\x85\xa5\x38\x82\x2e\x30\xbe\x17\xbc\xe1\x6d\x60\x04\x9f\x6a\xff\xdb\xa1\xfd\x04\x73\x8f\x08\x86\xa0\x8e\x60\xa8\xda\xdb\xc1\x29\x14\x43\x34\x23\x1c\x79\xde\x8e\x51\x14\xf2\xf7\x62\xd8\x5f\xbf\x23\x04\x65\x67\x0a\x7e\x2f\xba\xcd\x7d\x2f\xf8\x49\x38\x47\xd0\x13\x27\x4e\x63\x27\x51\x74\xc8\x71\x78\xed\x7d\xdb\x0d\xde\xb5\xe2\xc1\x13\x79\x45\x8b\xc2\x85\x77\xad\x55\xf7\xae\xf5\xab\x33\xf2\xc2\x06\x2b\x70\xc9\x79\x89\xd5\x6c\x30\x85\x5d\x74\x1b\xfd\x3f\x00\x00\xff\xff\x3d\x57\x95\x0a\x7e\x1d\x00\x00") +var _schemaGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\x5f\x6f\xdb\x46\x12\x7f\x16\x3f\xc5\xd8\x40\x0c\x32\x50\xa9\xb4\x28\x8a\x3b\xe5\x74\x40\xd1\x3a\x38\x5d\xaf\x4e\xd0\xc4\x7d\x09\x82\x94\x22\x97\xd2\xc6\xe4\x92\xe1\x2e\x6d\xab\xae\xbf\xfb\x61\x66\x76\xc9\xa5\x28\x29\x6e\x12\xe7\x25\xe2\xec\xfc\xfd\xed\xec\xcc\xec\x7a\x36\x83\x9f\xaa\x7a\xdb\xc8\xf5\xc6\xc0\x77\xcf\xbe\xfd\xe7\x37\x75\x23\xb4\x50\x06\x5e\x24\xa9\x58\x55\xd5\x15\x2c\x55\x1a\xc3\x8f\x45\x01\xc4\xa4\x01\xd7\x9b\x6b\x91\xc5\xc1\x6c\x06\x6f\x36\x52\x83\xae\xda\x26\x15\x90\x56\x99\x00\xa9\xa1\x90\xa9\x50\x5a\x64\xd0\xaa\x4c\x34\x60\x36\x02\x7e\xac\x93\x74\x23\xe0\xbb\xf8\x99\x5b\x85\xbc\x6a\x55\x86\x2a\xa4\x22\x96\xff\x2d\x7f\x3a\xbf\x78\x7d\x0e\xb9\x2c\x84\xa3\x35\x55\x65\x20\x93\x8d\x48\x4d\xd5\x6c\xa1\xca\xc1\x78\xf6\x4c\x23\x44\x1c\x04\x75\x92\x5e\x25\x6b\x01\x45\x95\x64\x41\x20\xcb\xba\x6a\x0c\x84\xc1\xe4\x54\xa8\xb4\xca\xa4\x5a\xcf\x3e\xe8\x4a\x9d\x06\x93\xd3\xbc\x34\xf8\x5f\x23\xf2\x42\xa4\xe6\x34\x08\x26\xa7\x6b\x69\x36\xed\x2a\x4e\xab\x72\x96\xdb\x80\xa5\x4a\xdb\x55\x62\xaa\x66\x26\x14\xf1\x7f\x8a\x67\xa6\xd3\x8d\x28\x93\x99\xc8\xd6\xe2\xef\xf0\xe7\x52\x14\xd9\x69\x10\x05\x88\xc2\x6b\xa2\x41\x23\x2c\xfe\x1a\x12\x05\x42\x99\xd8\x2e\x98\x4d\x62\xe0\x26\xd1\x14\xa6\xc8\x20\x6f\xaa\x12\x12\x48\xab\xb2\x2e\x24\x62\xad\x45\x03\x16\x8a\x38\x30\xdb\x5a\x38\x95\xda\x34\x6d\x6a\xe0\x2e\x98\x5c\x24\xa5\x00\x00\xa4\x48\xb5\xc6\x5f\xf0\x07\x62\x33\x3f\x55\x49\x29\xa6\x55\x29\x8d\x28\x6b\xb3\x3d\xfd\x23\x98\xfc\x54\xa9\x5c\xae\x81\x5c\xb0\xbf\x2d\x6f\x4a\x5f\x43\xee\xf3\x6c\x2d\x34\x00\xbc\x7d\xf7\x14\x7f\x7a\x9a\x11\x14\x3d\x64\x7e\x81\x71\x6b\x62\xa6\x9f\x3d\x33\x21\xb2\xc3\xbd\x54\x99\xb8\x15\x1a\xb9\xe9\x67\xcf\x2d\x79\x65\xc8\xfe\x9f\xaa\xba\x42\x4f\xa4\x32\x60\xff\x59\xf6\x0d\xae\x0c\x99\x5f\x55\x85\x4c\xb7\x00\xab\xaa\x2a\x86\xcc\x35\xad\x0c\xb8\xef\x69\x9f\x5e\x55\x5a\x1a\x59\x29\xc8\x84\x4e\x1b\xb9\x12\x1a\x12\x20\xbf\xa1\x76\x4b\x36\x7b\x79\x9b\xed\x66\x74\x72\xfd\x76\xb8\x70\x9c\xb7\xb3\x19\x30\x1e\x14\x98\xd3\xc2\xba\x0b\xa9\x4d\x1c\x4c\x7e\x95\xb7\x22\x5b\x2a\x14\x21\x9f\x67\x33\x58\xaa\x4c\xa6\x89\x11\x1a\x64\xee\x09\x60\xaa\x94\xc8\xfd\x8d\x54\x2c\x28\xd5\xd2\xea\x65\x5b\x44\x1a\xda\x2a\x89\xc4\xb6\x38\x5c\x76\x68\x9c\x95\x4c\xff\x8c\xa4\x64\xc1\x71\x4e\xf2\x3f\x2f\x33\x8f\xa7\xe7\x52\xe5\x55\xcf\xf6\x94\x62\x8e\xdf\x6c\x6b\x41\x0b\x56\x0c\x0d\x0e\xc5\xde\x24\x9e\xf2\x43\xd6\x4c\xb2\x93\xdd\xaf\xe5\x9f\x9e\x8f\x4f\xa5\x32\x3f\x7c\x3f\x92\xd2\xf2\xcf\x1d\x63\xe7\xaa\x2d\x75\xc7\xf6\xf6\xdd\xd0\x9c\x3b\x1f\xc8\x34\x94\xbb\x54\xf2\x63\xdb\x19\xf4\x72\xd3\x97\x6b\x89\x69\x28\x78\x21\x8b\x22\x59\x15\xe2\xa8\xa0\xb2\x4c\x43\xd1\x97\x35\x26\x67\x52\x1c\x15\xad\x2c\xd3\x50\xf4\x67\x91\x27\x6d\x61\x8e\xbb\x9b\x31\xd3\x5e\xc9\xdf\x93\x02\xc3\x95\xca\x88\x06\x0b\xe6\xdd\xfd\x1e\xc9\xf7\xd7\xc8\xb5\x03\x54\x9d\x25\x46\x38\xfb\x87\x80\x22\xa6\xf7\x7b\x1d\x58\x96\x65\x6b\x3a\xc4\x0e\x28\x90\x8e\x69\x28\xfb\x7b\x52\xc8\x0c\x4b\x3a\x6d\xb1\x57\x6e\x7c\xd9\xeb\x8e\x69\x27\xa3\x4c\xd5\x24\x6b\xf1\x8b\xd8\x1e\xc9\x43\xcd\x4c\xef\xaf\xc4\x76\xb7\x6c\xd9\x5a\xc2\xf9\x38\xfc\xec\x2b\x18\x53\x77\x0c\x0b\x85\xe4\xeb\xa3\x11\x6b\xc7\xb4\xa7\xfe\x51\x79\x1f\xd7\x03\x22\x7f\x46\x39\x20\xb9\x3d\xd5\xc0\x42\x72\xf0\xfc\xe3\x51\xdf\xc3\x78\xe4\xc4\xef\x30\xee\x9e\xf1\xdf\x44\xce\xc6\x87\x7c\x8d\xc8\xdf\x8f\xad\xff\x26\x72\x8b\x3d\x77\xbb\x9e\xf9\xc0\x49\xb6\x40\x1f\x39\xbb\x4b\x75\x2d\x1a\x2d\x76\x59\x25\x93\x77\xcd\x7f\x6c\x65\x23\xb2\x1d\xde\xc6\x92\xf7\xec\x1a\x57\xfe\xf1\xb6\x31\xfd\x33\xf6\x8d\x05\xfb\x8d\xf3\x6a\x56\x97\x54\x47\xa2\x75\xf3\x82\x5f\x17\x3f\x3d\x30\xec\xe1\xde\x37\x31\x78\x87\xab\x3b\x59\x9f\x38\x52\x8c\xd2\x85\xb8\xa1\xfd\x4c\x1b\x41\x0d\x35\x51\x0e\x11\x74\x8a\x61\xa1\x5f\xdc\xfb\x6b\x53\x35\x71\x90\xb7\x2a\x75\x92\xa1\xc8\xe0\x29\x72\xc4\x3f\x77\x1c\x91\x4d\x92\xbb\x60\xa2\x04\xcc\x17\x70\x86\x9f\x77\xc1\x04\x53\x73\xce\x18\x88\x2c\x7e\x93\xac\xa7\x48\xdb\xd6\x62\xde\xd1\x30\x9b\x83\x09\x9d\x8a\x8e\x88\x1f\x48\x64\xc4\xe7\x4c\xe4\x0f\x24\xdb\x3c\x9a\x13\xd9\x7e\x20\xdd\xe5\xcc\x1c\xe9\xee\x83\x17\x72\xab\x9f\x16\x72\xab\xff\x3e\x98\xc8\x1c\x1a\x91\xa3\xcb\xbc\xf2\x9c\x3e\x4f\x16\xa0\x64\x81\xe1\x4c\x94\x40\x32\x2c\xba\xf0\x1b\x91\x47\x24\xda\x08\xd3\x36\x0a\x94\xe8\x91\xe5\xc6\x3f\x86\x96\xc7\x95\xe3\xd8\x92\x6c\x98\x67\xae\xd1\xfb\xe8\x86\x3c\x44\x4e\x41\x34\x0d\x7e\xdf\x05\x13\x4d\x4e\x9f\x11\xfd\x6e\x80\x1f\xfd\xcb\x7b\x10\x71\x5a\x18\xae\x20\x65\x3a\xd8\x1c\xb7\x62\x77\x88\xba\xfa\xdc\x5f\x20\xca\x70\x4b\xdc\x52\xbf\x2f\xae\x37\xcf\x7b\x1f\x5c\x23\x0e\x26\x5d\xfb\xed\x57\x1d\x05\x57\x6d\x87\x9b\xf7\x7a\x5d\xcf\xe3\xcd\x20\xdb\x7e\x2f\x9c\x93\xed\x41\x77\xec\x39\xbb\xa6\x37\xef\x62\xee\x3a\x5c\x30\xf1\x4e\xcf\xdc\x2e\xf7\x14\x5c\xef\xfb\x1e\xad\x17\x42\x85\x79\x16\xf7\xd4\x88\x94\xb8\x0e\xd2\xd9\xe8\x28\x5d\x6e\xe9\x9c\xc0\x86\x45\x9f\x50\x2e\x6d\x64\x31\x85\xbc\x34\xf1\x39\x6e\x69\x1e\x9e\x96\x52\x6b\x3c\xc7\x54\x7a\x24\x0a\xe5\x55\x63\x33\xe7\xc9\xc7\xd3\x29\xea\xc2\x2d\x8d\x3a\xdd\x38\xb1\xcd\x17\x40\xa3\x1a\xfa\x87\x23\x5c\xf4\x9c\xe9\x27\x0b\x78\x46\xe6\x74\x4e\x74\x58\xc0\x19\x2e\x90\x30\x16\x4b\x9e\xa3\xed\xc4\x00\x34\x78\x40\x9a\x28\x58\x09\xa0\x3b\xa5\xc8\xc0\x54\xc4\xb3\x16\x4a\x34\x09\xe5\x2a\x4a\xbe\xa8\x1a\x10\xb7\x49\x59\x17\x62\x0a\xaa\x32\x78\x35\x68\x55\x4a\xcd\xb9\x90\x57\x02\x8c\x2c\x45\x7c\x51\xdd\xc4\xe4\xe5\x7b\x4a\x5a\xf4\x13\xab\x53\xfc\x6b\xd2\xe8\x4d\x52\x84\xfd\xfe\x46\xcf\x89\xc1\x43\x48\xe7\xf1\x60\x6a\x5a\x78\xd9\xe0\x82\xb7\x59\x4c\xe5\x03\x65\xfb\xe1\xf8\xf2\x72\xf9\x33\x9c\x9d\x8d\x33\x88\x74\x9b\x6d\x8d\xbe\xd8\xeb\x31\x09\xbc\xcc\x7d\x6f\x82\x09\xaa\x37\xdb\x3a\xfe\x45\xaa\x2c\x8c\x50\xd8\x71\xbf\xc0\xa3\xfa\xd7\x5f\xb4\x7a\xd1\x96\x4b\xc5\xcb\xcf\x3c\xda\xcb\xd6\x30\xf1\x5b\x47\x44\xca\xb3\x28\x7e\x4d\x55\x9a\xd7\x9c\xf3\x1d\x0d\x3d\x3b\x98\x18\xe2\xb6\x16\xa9\xe1\xbc\x08\x11\xea\x30\x82\x27\x3a\xa2\xf4\x68\x5b\x99\x0d\x37\xf1\x74\x3a\x52\x8f\x31\xdd\xfb\x25\x4b\xe7\x53\x34\x63\xeb\x96\xdd\x12\x7b\x93\xe6\xcd\xa7\x8d\xf7\x6e\xe6\xdd\xdc\x8a\xbf\x2a\x48\xe0\xbf\xaf\x5f\x5e\xa0\x30\xb5\x55\x9b\x37\x99\xe0\xbc\x21\x16\x54\x60\x85\xab\xd5\x07\x0c\x80\xff\xb3\x05\x6f\x60\x34\xd4\xce\x36\x76\x6b\x6b\x29\x82\x70\x05\x6f\xdf\xad\xb6\x46\x70\x0a\x79\xb5\x8f\x4a\x1f\xcb\x22\x74\x7c\x77\x9f\xbb\xcb\x28\x7f\x86\x91\xdf\x56\xa4\xe2\x27\x96\x70\x67\xe7\x59\x24\x8a\xe8\x68\x91\x08\xe7\x97\xcd\x59\x1d\x63\x05\xe7\xde\xec\x78\x39\x5f\x4f\x3e\x7d\xa2\x6d\x54\x4f\x3e\xce\xe1\xc9\x35\x1e\x60\x2e\xc9\x28\xce\x87\x98\xc7\x80\xce\x56\x92\x0b\x9a\x19\x9c\xa1\xce\x91\xaf\x61\x0b\xb3\x05\xcf\x22\x65\x7f\xa2\xd6\x82\x3a\x91\xe6\x03\x17\xf3\xac\xb2\x80\xa4\xae\x85\xca\x42\x4b\x98\xf6\x3d\xdf\x6b\x47\x61\x14\xd9\x1a\x64\xdf\x26\xfc\x00\xec\x4b\xc6\x63\x86\x20\xb3\xdb\x3e\x08\xeb\x03\x29\xb6\x0b\x32\xbb\x1d\x78\x4b\x01\xba\x17\x16\x2f\xc4\xa5\x73\xff\x8c\x7e\xd1\x19\xa4\xb0\x6d\x0f\x42\x3d\x0c\x03\xae\x70\x0e\xcc\xbb\x15\xfe\xa6\x25\xbf\x25\xe2\x52\xdf\x10\x07\x8d\x06\x97\x86\x6d\xe6\x3e\xda\x9b\x6e\xf4\xbc\xf3\xf5\xb3\x6d\xd7\x0c\x3f\x0c\x7d\x7d\x3b\x56\x70\x50\xee\x75\x64\x8b\xcd\xa5\x2a\x07\xe5\x86\x6b\x86\xe6\x46\x23\xaf\x85\x82\x55\x9b\xe7\xa2\x01\xaa\x32\x76\x7c\x72\x8f\x4c\x54\x39\x76\x34\x84\xab\x36\xb7\x65\x02\xe7\x24\x26\x4e\x0f\x15\x8b\x01\x0c\xe4\x61\xa7\x0e\x15\x4d\x41\x1f\x07\x42\x34\x8d\x9f\x8a\x79\x9f\x88\xda\x66\x04\x67\x62\x67\x23\x8f\x6d\x75\xd6\xe1\x58\xf3\x58\xf5\x4e\x9d\xf6\xcb\x74\x5f\x88\xe8\xa7\xb6\xa3\x81\xa9\x2c\x3c\x76\xbc\xf4\x4b\xa8\x45\x2c\xd4\x60\x71\x89\x60\x54\xce\x76\x8b\x2e\x01\x87\xde\xd1\x3b\xd9\xe0\x6c\xd3\x63\xda\x03\x4e\xb6\x0f\x92\x9c\x42\xe9\x1d\x57\x7e\x7c\x43\x5e\x7b\xa9\xf1\xf5\x5b\xbf\xca\xdb\xa8\x87\x70\x0f\x5a\x1d\x50\x64\xe0\xc3\x60\x17\xf2\x7e\x0f\x26\xd8\xe5\xac\xf6\x7e\xbc\x1e\xd6\x31\x64\xdb\x63\x68\x68\x89\x4c\xe1\x50\xd2\xbd\x41\x2c\xe0\xcc\xfd\x66\x7e\x2a\x20\xb6\x6c\x7c\xa0\x83\xef\x5e\x31\x89\x68\x1a\x5b\x0e\xbc\x27\xca\x39\xc8\x69\xaf\xdc\x25\x8f\x57\x9e\x6c\x81\x01\x9d\xf7\xfd\xfb\x30\x68\x7f\x7b\x57\xf6\x83\xf6\x30\xcc\x1e\xb2\x37\x87\xf0\x72\xc1\x13\xcf\xa7\xc2\xf6\x6e\x59\x7c\x0e\xf6\xe6\xb3\x5f\x2f\x0f\xa6\x33\xbf\x8c\xfb\xc8\x0d\xca\xec\x03\x80\xd3\x31\xbf\xbb\x2f\xe8\x3e\x40\xfa\xa2\x07\xf9\x37\x28\xb4\x07\x1d\xb4\xaf\xf1\xbe\x87\xc3\x0a\xfd\x20\x17\xed\x6b\xff\x02\x58\x9d\xe5\xdd\xef\x66\x0e\x7c\xad\x8c\xa0\xaf\x51\xbd\x3f\x32\x87\x93\x6e\x10\xc7\x61\xf6\x84\xef\x32\x38\xe5\x8a\x46\xa6\x76\x6c\xf5\x14\xa3\x07\x6a\x0a\xd5\x15\x17\x3e\x7f\x86\x8f\xc3\xbc\xa8\x12\xf3\xc3\xf7\x1c\xc5\x49\x75\xe5\x0b\xfb\xed\xa5\x55\x3c\xef\x8a\x9d\xb9\x96\xe7\xdf\xee\x4a\x34\xe7\x3b\x91\x7f\x25\xd2\x37\xd2\xa4\x1b\x30\x6c\xbd\xbb\x1d\x3c\x47\x4b\x69\xa2\x05\x18\xf8\xb7\x7f\x51\x58\x2a\xf3\x0f\xbc\x28\x18\xf8\xd7\x0e\xf9\x87\xef\xe7\x58\x5d\x76\x6f\x21\x7c\xd1\x52\xd1\x7e\x75\x97\x72\xbf\xbe\x4b\x79\x50\x61\xdb\x6b\x1c\x65\xfa\x6c\xe6\x1d\x6f\xb8\x69\x92\x5a\xfb\x7f\x70\xb1\xf4\x44\x65\x5c\x53\x1d\xa1\x14\x66\x53\x65\x70\x23\xcd\x06\x1a\x91\x56\xd7\xdc\x4a\x85\xd2\x6d\x23\x40\x55\x50\x27\x4a\xa6\x1a\xa4\x02\xdb\xf7\xa4\x5a\xdb\x3e\xe1\x95\x93\x3c\xf3\x9e\xaa\xc1\x12\x23\x78\xfb\xae\xff\xbb\xc8\x7d\x04\xa1\xad\x1c\x1e\x79\x77\x54\xcf\x04\x36\x73\x7b\x6b\xb1\xad\xf1\x9a\x6f\x60\xe4\x1c\x76\xc5\xeb\x41\x25\xa1\xcb\xe0\x20\x25\x9e\xbc\x71\xd1\xb1\xf3\x76\xf0\xc8\xb3\x29\x5c\x53\x09\xcf\x5d\x15\xa1\x2c\xa4\x5a\x19\xf6\x47\x33\xcf\x62\x17\xc0\x74\x07\x5d\x1e\x7b\x47\xe0\x32\xf9\x4b\xa1\xf4\x67\xf9\xd1\xd5\x86\x87\x6f\x06\x0e\x19\x1f\x03\xb7\x41\x34\x03\xe8\x18\x36\x61\x87\xfe\xbd\xa8\xf9\xc2\x63\xe0\xdc\x38\x3d\x82\xce\x2d\x7c\x29\x78\xc3\x7b\xc4\x08\x3e\xd9\xfd\xc1\xb4\x7b\xe1\x7d\x44\x04\x5d\x50\x7b\x30\x94\xdd\xbd\xe2\x18\x8a\x2e\x9a\x11\x8e\xfc\xf7\xc9\x11\x8a\x4c\xfe\x52\x0c\xfd\x79\x6d\x84\x20\x4f\x62\x8c\xdf\xaf\xfd\xa8\xf7\x28\xf8\x71\x38\x7b\xd0\x63\x27\x8e\x63\xc7\x51\x8c\x90\xe3\x5e\x3c\x42\x8e\xc9\x5f\x8a\xdc\xb1\x89\x82\x3b\xbf\x45\x0e\x19\x1f\x11\x38\x8e\x66\x0f\x70\x1b\x3b\x89\x1c\x03\x8e\x83\x18\x01\x67\x27\x84\x11\x72\x96\xfe\xa5\xd0\x1d\x1d\x76\x42\x3b\x95\x20\xf9\x95\x37\xef\x3c\x0a\x78\x36\xa0\x3d\xe8\xd5\x6e\x48\x3a\x06\x9f\x0d\xa4\xc7\x8f\x42\xec\xde\x91\xcc\xe0\x0d\x31\x1a\x7c\xa1\x63\x38\xa9\x18\xf7\x86\xb8\xe8\xdf\x10\x5f\x99\x86\x1f\x22\x61\x01\x26\x3e\x2f\x44\x19\x0e\xda\xbf\x09\xee\x83\xff\x07\x00\x00\xff\xff\x45\x50\x40\xa6\xb1\x24\x00\x00") func schemaGoBytes() ([]byte, error) { return bindataRead( @@ -113,7 +113,7 @@ func schemaGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "schema.go", size: 7550, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "schema.go", size: 9393, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/load/load.go b/entc/load/load.go index d511c7a92..574b75576 100644 --- a/entc/load/load.go +++ b/entc/load/load.go @@ -7,7 +7,6 @@ package load import ( "bytes" - "encoding/json" "fmt" "go/ast" "go/format" @@ -34,9 +33,7 @@ import ( type SchemaSpec struct { // Schemas are the schema descriptors. Schemas []*Schema - // PkgPath is the path where the schema package reside. - // Note that path can be either a package path (e.g. github.com/a8m/x) - // or a filepath (e.g. ./ent/schema). + // PkgPath is the package path of the schema. PkgPath string } @@ -70,19 +67,22 @@ func (c *Config) Load() (*SchemaSpec, error) { if err != nil { return nil, fmt.Errorf("format template: %v", err) } - target := fmt.Sprintf("%s.go", filename(pkgPath)) + if err := os.MkdirAll(".entc", os.ModePerm); err != nil { + return nil, err + } + target := fmt.Sprintf(".entc/%s.go", filename(pkgPath)) if err := ioutil.WriteFile(target, buf, 0644); err != nil { return nil, fmt.Errorf("write file %s: %v", target, err) } - defer os.Remove(target) + defer os.RemoveAll(".entc") out, err := run(target) if err != nil { return nil, err } spec := &SchemaSpec{PkgPath: pkgPath} for _, line := range strings.Split(out, "\n") { - schema := &Schema{} - if err := json.Unmarshal([]byte(line), schema); err != nil { + schema, err := UnmarshalSchema([]byte(line)) + if err != nil { return nil, fmt.Errorf("unmarshal schema %s: %v", line, err) } spec.Schemas = append(spec.Schemas, schema) @@ -97,7 +97,7 @@ var entInterface = reflect.TypeOf(struct{ ent.Interface }{}).Field(0).Type func (c *Config) load() (string, error) { pkgs, err := packages.Load(&packages.Config{Mode: packages.LoadSyntax}, c.Path, entInterface.PkgPath()) if err != nil { - return "", err + return "", fmt.Errorf("loading package: %v", err) } if len(pkgs) < 2 { return "", fmt.Errorf("missing package information for: %s", c.Path) @@ -129,7 +129,7 @@ func (c *Config) load() (string, error) { c.Names = names } sort.Strings(c.Names) - return pkg.PkgPath, err + return pkg.PkgPath, nil } //go:generate go run github.com/go-bindata/go-bindata/go-bindata -pkg=internal -o=internal/bindata.go -modtime=1 ./template/... schema.go @@ -188,10 +188,10 @@ func filename(pkg string) string { // run 'go run' command and return its output. func run(target string) (string, error) { cmd := exec.Command("go", "run", target) - stdout := bytes.NewBuffer(nil) stderr := bytes.NewBuffer(nil) - cmd.Stdout = stdout + stdout := bytes.NewBuffer(nil) cmd.Stderr = stderr + cmd.Stdout = stdout if err := cmd.Run(); err != nil { return "", fmt.Errorf("entc/load: %s", stderr) } diff --git a/entc/load/schema.go b/entc/load/schema.go index 459648014..5a65082e6 100644 --- a/entc/load/schema.go +++ b/entc/load/schema.go @@ -21,13 +21,15 @@ type Schema struct { Edges []*Edge `json:"edges,omitempty"` Fields []*Field `json:"fields,omitempty"` Indexes []*Index `json:"indexes,omitempty"` + Hooks int `json:"hooks,omitempty"` + Policy bool `json:"policy,omitempty"` } // Position describes a field position in the schema. type Position struct { - Index int // field index in the field list. - MixedIn bool // indicates if the field was mixed-in. - MixinIndex int // mixin index in the mixin list. + Index int // Field index in the field list. + MixedIn bool // Indicates if the field was mixed-in. + MixinIndex int // Mixin index in the mixin list. } // Field represents an ent.Field that was loaded from a complied user package. @@ -132,7 +134,7 @@ func MarshalSchema(schema ent.Interface) (b []byte, err error) { Name: indirect(reflect.TypeOf(schema)).Name(), } if err := s.loadFields(schema); err != nil { - return nil, err + return nil, fmt.Errorf("schema %q: %v", s.Name, err) } edges, err := safeEdges(schema) if err != nil { @@ -154,24 +156,44 @@ func MarshalSchema(schema ent.Interface) (b []byte, err error) { StorageKey: idx.StorageKey, }) } + if err := s.loadHooks(schema); err != nil { + return nil, fmt.Errorf("schema %q: %v", s.Name, err) + } + if err := s.loadPolicy(schema); err != nil { + return nil, fmt.Errorf("schema %q: %v", s.Name, err) + } return json.Marshal(s) } +// UnmarshalSchema decodes the given buffer to a loaded schema. +func UnmarshalSchema(buf []byte) (*Schema, error) { + s := &Schema{} + if err := json.Unmarshal(buf, s); err != nil { + return nil, err + } + for _, f := range s.Fields { + if err := f.defaults(); err != nil { + return nil, err + } + } + return s, nil +} + // loadFields loads field to schema from ent.Interface. func (s *Schema) loadFields(schema ent.Interface) error { mixin, err := safeMixin(schema) if err != nil { - return fmt.Errorf("schema %q: %v", s.Name, err) + return err } for i, mx := range mixin { fields, err := safeFields(mx) if err != nil { - return fmt.Errorf("schema %q: %v", s.Name, err) + return err } for j, f := range fields { sf, err := NewField(f.Descriptor()) if err != nil { - return fmt.Errorf("schema %q: %v", s.Name, err) + return err } sf.Position = &Position{ Index: j, @@ -183,12 +205,12 @@ func (s *Schema) loadFields(schema ent.Interface) error { } fields, err := safeFields(schema) if err != nil { - return fmt.Errorf("schema %q: %v", s.Name, err) + return err } for i, f := range fields { sf, err := NewField(f.Descriptor()) if err != nil { - return fmt.Errorf("schema %q: %v", s.Name, err) + return err } sf.Position = &Position{Index: i} s.Fields = append(s.Fields, sf) @@ -196,6 +218,41 @@ func (s *Schema) loadFields(schema ent.Interface) error { return nil } +func (s *Schema) loadHooks(schema ent.Interface) error { + hooks, err := safeHooks(schema) + if err != nil { + return err + } + s.Hooks = len(hooks) + return nil +} + +func (s *Schema) loadPolicy(schema ent.Interface) error { + policy, err := safePolicy(schema) + if err != nil { + return err + } + s.Policy = policy != nil + return nil +} + +func (f *Field) defaults() error { + if !f.Default || !f.Info.Numeric() { + return nil + } + n, ok := f.DefaultValue.(float64) + if !ok { + return fmt.Errorf("unexpected default value type for field: %q", f.Name) + } + switch t := f.Info.Type; { + case t >= field.TypeInt8 && t <= field.TypeInt64: + f.DefaultValue = int64(n) + case t >= field.TypeUint8 && t <= field.TypeUint64: + f.DefaultValue = uint64(n) + } + return nil +} + // safeFields wraps the schema.Fields and mixin.Fields method with recover to ensure no panics in marshaling. func safeFields(fd interface{ Fields() []ent.Field }) (fields []ent.Field, err error) { defer func() { @@ -240,6 +297,28 @@ func safeMixin(schema ent.Interface) (mixin []ent.Mixin, err error) { return schema.Mixin(), nil } +// safeHooks wraps the schema.Hooks method with recover to ensure no panics in marshaling. +func safeHooks(schema ent.Interface) (hooks []ent.Hook, err error) { + defer func() { + if v := recover(); v != nil { + err = fmt.Errorf("schema.Hooks panics: %v", v) + hooks = nil + } + }() + return schema.Hooks(), nil +} + +// safePolicy wraps the schema.Policy method with recover to ensure no panics in marshaling. +func safePolicy(schema ent.Interface) (policy ent.Policy, err error) { + defer func() { + if v := recover(); v != nil { + err = fmt.Errorf("schema.Policy panics: %v", v) + policy = nil + } + }() + return schema.Policy(), nil +} + func indirect(t reflect.Type) reflect.Type { for t.Kind() == reflect.Ptr { t = t.Elem() diff --git a/entc/load/template/main.tmpl b/entc/load/template/main.tmpl index 3972b6f58..7988646f3 100644 --- a/entc/load/template/main.tmpl +++ b/entc/load/template/main.tmpl @@ -37,7 +37,7 @@ func main() { } func fail(err error) { - os.Stderr.WriteString(err.Error()) + os.Stderr.WriteString(err.Error()+"\n") os.Exit(1) } diff --git a/examples/edgeindex/ent/city/city.go b/examples/edgeindex/ent/city/city.go index d8edfd468..7f7f56468 100644 --- a/examples/edgeindex/ent/city/city.go +++ b/examples/edgeindex/ent/city/city.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the city type in the database. Label = "city" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeStreets holds the string denoting the streets edge name in mutations. + EdgeStreets = "streets" + // Table holds the table name of the city in the database. Table = "cities" // StreetsTable is the table the holds the streets relation/edge. diff --git a/examples/edgeindex/ent/city_create.go b/examples/edgeindex/ent/city_create.go index 76751f09d..b502c4cf8 100644 --- a/examples/edgeindex/ent/city_create.go +++ b/examples/edgeindex/ent/city_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/edgeindex/ent/city" @@ -19,24 +20,19 @@ import ( // CityCreate is the builder for creating a City entity. type CityCreate struct { config - name *string - streets map[int]struct{} + mutation *CityMutation + hooks []Hook } // SetName sets the name field. func (cc *CityCreate) SetName(s string) *CityCreate { - cc.name = &s + cc.mutation.SetName(s) return cc } // AddStreetIDs adds the streets edge to Street by ids. func (cc *CityCreate) AddStreetIDs(ids ...int) *CityCreate { - if cc.streets == nil { - cc.streets = make(map[int]struct{}) - } - for i := range ids { - cc.streets[ids[i]] = struct{}{} - } + cc.mutation.AddStreetIDs(ids...) return cc } @@ -51,10 +47,33 @@ func (cc *CityCreate) AddStreets(s ...*Street) *CityCreate { // Save creates the City in the database. func (cc *CityCreate) Save(ctx context.Context) (*City, error) { - if cc.name == nil { + if _, ok := cc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return cc.sqlSave(ctx) + var ( + err error + node *City + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CityMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -77,15 +96,15 @@ func (cc *CityCreate) sqlSave(ctx context.Context) (*City, error) { }, } ) - if value := cc.name; value != nil { + if value, ok := cc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: city.FieldName, }) - c.Name = *value + c.Name = value } - if nodes := cc.streets; len(nodes) > 0 { + if nodes := cc.mutation.StreetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -99,7 +118,7 @@ func (cc *CityCreate) sqlSave(ctx context.Context) (*City, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/edgeindex/ent/city_delete.go b/examples/edgeindex/ent/city_delete.go index 0e74c7ccc..ba3824fe4 100644 --- a/examples/edgeindex/ent/city_delete.go +++ b/examples/edgeindex/ent/city_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CityDelete is the builder for deleting a City entity. type CityDelete struct { config + hooks []Hook + mutation *CityMutation predicates []predicate.City } @@ -30,7 +33,30 @@ func (cd *CityDelete) Where(ps ...predicate.City) *CityDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CityDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CityMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/edgeindex/ent/city_update.go b/examples/edgeindex/ent/city_update.go index 3289c5979..20875c8b5 100644 --- a/examples/edgeindex/ent/city_update.go +++ b/examples/edgeindex/ent/city_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,10 +21,9 @@ import ( // CityUpdate is the builder for updating City entities. type CityUpdate struct { config - name *string - streets map[int]struct{} - removedStreets map[int]struct{} - predicates []predicate.City + hooks []Hook + mutation *CityMutation + predicates []predicate.City } // Where adds a new predicate for the builder. @@ -34,18 +34,13 @@ func (cu *CityUpdate) Where(ps ...predicate.City) *CityUpdate { // SetName sets the name field. func (cu *CityUpdate) SetName(s string) *CityUpdate { - cu.name = &s + cu.mutation.SetName(s) return cu } // AddStreetIDs adds the streets edge to Street by ids. func (cu *CityUpdate) AddStreetIDs(ids ...int) *CityUpdate { - if cu.streets == nil { - cu.streets = make(map[int]struct{}) - } - for i := range ids { - cu.streets[ids[i]] = struct{}{} - } + cu.mutation.AddStreetIDs(ids...) return cu } @@ -60,12 +55,7 @@ func (cu *CityUpdate) AddStreets(s ...*Street) *CityUpdate { // RemoveStreetIDs removes the streets edge to Street by ids. func (cu *CityUpdate) RemoveStreetIDs(ids ...int) *CityUpdate { - if cu.removedStreets == nil { - cu.removedStreets = make(map[int]struct{}) - } - for i := range ids { - cu.removedStreets[ids[i]] = struct{}{} - } + cu.mutation.RemoveStreetIDs(ids...) return cu } @@ -80,7 +70,31 @@ func (cu *CityUpdate) RemoveStreets(s ...*Street) *CityUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CityUpdate) Save(ctx context.Context) (int, error) { - return cu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CityMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -123,14 +137,14 @@ func (cu *CityUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := cu.name; value != nil { + if value, ok := cu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: city.FieldName, }) } - if nodes := cu.removedStreets; len(nodes) > 0 { + if nodes := cu.mutation.RemovedStreetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -144,12 +158,12 @@ func (cu *CityUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.streets; len(nodes) > 0 { + if nodes := cu.mutation.StreetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -163,7 +177,7 @@ func (cu *CityUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -182,26 +196,19 @@ func (cu *CityUpdate) sqlSave(ctx context.Context) (n int, err error) { // CityUpdateOne is the builder for updating a single City entity. type CityUpdateOne struct { config - id int - name *string - streets map[int]struct{} - removedStreets map[int]struct{} + hooks []Hook + mutation *CityMutation } // SetName sets the name field. func (cuo *CityUpdateOne) SetName(s string) *CityUpdateOne { - cuo.name = &s + cuo.mutation.SetName(s) return cuo } // AddStreetIDs adds the streets edge to Street by ids. func (cuo *CityUpdateOne) AddStreetIDs(ids ...int) *CityUpdateOne { - if cuo.streets == nil { - cuo.streets = make(map[int]struct{}) - } - for i := range ids { - cuo.streets[ids[i]] = struct{}{} - } + cuo.mutation.AddStreetIDs(ids...) return cuo } @@ -216,12 +223,7 @@ func (cuo *CityUpdateOne) AddStreets(s ...*Street) *CityUpdateOne { // RemoveStreetIDs removes the streets edge to Street by ids. func (cuo *CityUpdateOne) RemoveStreetIDs(ids ...int) *CityUpdateOne { - if cuo.removedStreets == nil { - cuo.removedStreets = make(map[int]struct{}) - } - for i := range ids { - cuo.removedStreets[ids[i]] = struct{}{} - } + cuo.mutation.RemoveStreetIDs(ids...) return cuo } @@ -236,7 +238,31 @@ func (cuo *CityUpdateOne) RemoveStreets(s ...*Street) *CityUpdateOne { // Save executes the query and returns the updated entity. func (cuo *CityUpdateOne) Save(ctx context.Context) (*City, error) { - return cuo.sqlSave(ctx) + + var ( + err error + node *City + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CityMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -267,20 +293,24 @@ func (cuo *CityUpdateOne) sqlSave(ctx context.Context) (c *City, err error) { Table: city.Table, Columns: city.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeInt, Column: city.FieldID, }, }, } - if value := cuo.name; value != nil { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing City.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: city.FieldName, }) } - if nodes := cuo.removedStreets; len(nodes) > 0 { + if nodes := cuo.mutation.RemovedStreetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -294,12 +324,12 @@ func (cuo *CityUpdateOne) sqlSave(ctx context.Context) (c *City, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.streets; len(nodes) > 0 { + if nodes := cuo.mutation.StreetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -313,7 +343,7 @@ func (cuo *CityUpdateOne) sqlSave(ctx context.Context) (c *City, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/edgeindex/ent/client.go b/examples/edgeindex/ent/client.go index 72365fe6d..0fa87b15d 100644 --- a/examples/edgeindex/ent/client.go +++ b/examples/edgeindex/ent/client.go @@ -34,14 +34,17 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - City: NewCityClient(c), - Street: NewStreetClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.City = NewCityClient(c.config) + c.Street = NewStreetClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -69,7 +72,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, City: NewCityClient(cfg), @@ -88,13 +91,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - City: NewCityClient(cfg), - Street: NewStreetClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -102,6 +102,13 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.City.Use(hooks...) + c.Street.Use(hooks...) +} + // CityClient is a client for the City schema. type CityClient struct { config @@ -112,14 +119,22 @@ func NewCityClient(c config) *CityClient { return &CityClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `city.Hooks(f(g(h())))`. +func (c *CityClient) Use(hooks ...Hook) { + c.hooks.City = append(c.hooks.City, hooks...) +} + // Create returns a create builder for City. func (c *CityClient) Create() *CityCreate { - return &CityCreate{config: c.config} + mutation := newCityMutation(c.config, OpCreate) + return &CityCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for City. func (c *CityClient) Update() *CityUpdate { - return &CityUpdate{config: c.config} + mutation := newCityMutation(c.config, OpUpdate) + return &CityUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -129,12 +144,15 @@ func (c *CityClient) UpdateOne(ci *City) *CityUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CityClient) UpdateOneID(id int) *CityUpdateOne { - return &CityUpdateOne{config: c.config, id: id} + mutation := newCityMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CityUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for City. func (c *CityClient) Delete() *CityDelete { - return &CityDelete{config: c.config} + mutation := newCityMutation(c.config, OpDelete) + return &CityDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -144,7 +162,10 @@ func (c *CityClient) DeleteOne(ci *City) *CityDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CityClient) DeleteOneID(id int) *CityDeleteOne { - return &CityDeleteOne{c.Delete().Where(city.ID(id))} + builder := c.Delete().Where(city.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CityDeleteOne{builder} } // Create returns a query builder for City. @@ -180,6 +201,11 @@ func (c *CityClient) QueryStreets(ci *City) *StreetQuery { return query } +// Hooks returns the client hooks. +func (c *CityClient) Hooks() []Hook { + return c.hooks.City +} + // StreetClient is a client for the Street schema. type StreetClient struct { config @@ -190,14 +216,22 @@ func NewStreetClient(c config) *StreetClient { return &StreetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `street.Hooks(f(g(h())))`. +func (c *StreetClient) Use(hooks ...Hook) { + c.hooks.Street = append(c.hooks.Street, hooks...) +} + // Create returns a create builder for Street. func (c *StreetClient) Create() *StreetCreate { - return &StreetCreate{config: c.config} + mutation := newStreetMutation(c.config, OpCreate) + return &StreetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Street. func (c *StreetClient) Update() *StreetUpdate { - return &StreetUpdate{config: c.config} + mutation := newStreetMutation(c.config, OpUpdate) + return &StreetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -207,12 +241,15 @@ func (c *StreetClient) UpdateOne(s *Street) *StreetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *StreetClient) UpdateOneID(id int) *StreetUpdateOne { - return &StreetUpdateOne{config: c.config, id: id} + mutation := newStreetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &StreetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Street. func (c *StreetClient) Delete() *StreetDelete { - return &StreetDelete{config: c.config} + mutation := newStreetMutation(c.config, OpDelete) + return &StreetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -222,7 +259,10 @@ func (c *StreetClient) DeleteOne(s *Street) *StreetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *StreetClient) DeleteOneID(id int) *StreetDeleteOne { - return &StreetDeleteOne{c.Delete().Where(street.ID(id))} + builder := c.Delete().Where(street.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &StreetDeleteOne{builder} } // Create returns a query builder for Street. @@ -257,3 +297,8 @@ func (c *StreetClient) QueryCity(s *Street) *CityQuery { return query } + +// Hooks returns the client hooks. +func (c *StreetClient) Hooks() []Hook { + return c.hooks.Street +} diff --git a/examples/edgeindex/ent/config.go b/examples/edgeindex/ent/config.go index dd64c4cf6..b9830f9cf 100644 --- a/examples/edgeindex/ent/config.go +++ b/examples/edgeindex/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,14 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + City []ent.Hook + Street []ent.Hook } // Options applies the options on the config object. diff --git a/examples/edgeindex/ent/ent.go b/examples/edgeindex/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/edgeindex/ent/ent.go +++ b/examples/edgeindex/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/edgeindex/ent/hook/hook.go b/examples/edgeindex/ent/hook/hook.go new file mode 100644 index 000000000..129e3f4f9 --- /dev/null +++ b/examples/edgeindex/ent/hook/hook.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/edgeindex/ent" +) + +// The CityFunc type is an adapter to allow the use of ordinary +// function as City mutator. +type CityFunc func(context.Context, *ent.CityMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CityFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CityMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CityMutation", m) + } + return f(ctx, mv) +} + +// The StreetFunc type is an adapter to allow the use of ordinary +// function as Street mutator. +type StreetFunc func(context.Context, *ent.StreetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f StreetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.StreetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.StreetMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/edgeindex/ent/mutation.go b/examples/edgeindex/ent/mutation.go new file mode 100644 index 000000000..1d99420b0 --- /dev/null +++ b/examples/edgeindex/ent/mutation.go @@ -0,0 +1,616 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/edgeindex/ent/city" + "github.com/facebookincubator/ent/examples/edgeindex/ent/street" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCity = "City" + TypeStreet = "Street" +) + +// CityMutation represents an operation that mutate the Cities +// nodes in the graph. +type CityMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + streets map[int]struct{} + removedstreets map[int]struct{} +} + +var _ ent.Mutation = (*CityMutation)(nil) + +// newCityMutation creates new mutation for $n.Name. +func newCityMutation(c config, op Op) *CityMutation { + return &CityMutation{ + config: c, + op: op, + typ: TypeCity, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CityMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CityMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CityMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *CityMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *CityMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *CityMutation) ResetName() { + m.name = nil +} + +// AddStreetIDs adds the streets edge to Street by ids. +func (m *CityMutation) AddStreetIDs(ids ...int) { + if m.streets == nil { + m.streets = make(map[int]struct{}) + } + for i := range ids { + m.streets[ids[i]] = struct{}{} + } +} + +// RemoveStreetIDs removes the streets edge to Street by ids. +func (m *CityMutation) RemoveStreetIDs(ids ...int) { + if m.removedstreets == nil { + m.removedstreets = make(map[int]struct{}) + } + for i := range ids { + m.removedstreets[ids[i]] = struct{}{} + } +} + +// RemovedStreets returns the removed ids of streets. +func (m *CityMutation) RemovedStreetsIDs() (ids []int) { + for id := range m.removedstreets { + ids = append(ids, id) + } + return +} + +// StreetsIDs returns the streets ids in the mutation. +func (m *CityMutation) StreetsIDs() (ids []int) { + for id := range m.streets { + ids = append(ids, id) + } + return +} + +// ResetStreets reset all changes of the streets edge. +func (m *CityMutation) ResetStreets() { + m.streets = nil + m.removedstreets = nil +} + +// Op returns the operation name. +func (m *CityMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (City). +func (m *CityMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CityMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, city.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CityMutation) Field(name string) (ent.Value, bool) { + switch name { + case city.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CityMutation) SetField(name string, value ent.Value) error { + switch name { + case city.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown City field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CityMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CityMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CityMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown City numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CityMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CityMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CityMutation) ClearField(name string) error { + return fmt.Errorf("unknown City nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CityMutation) ResetField(name string) error { + switch name { + case city.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown City field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CityMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.streets != nil { + edges = append(edges, city.EdgeStreets) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CityMutation) AddedIDs(name string) []ent.Value { + switch name { + case city.EdgeStreets: + ids := make([]ent.Value, 0, len(m.streets)) + for id := range m.streets { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CityMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedstreets != nil { + edges = append(edges, city.EdgeStreets) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CityMutation) RemovedIDs(name string) []ent.Value { + switch name { + case city.EdgeStreets: + ids := make([]ent.Value, 0, len(m.removedstreets)) + for id := range m.removedstreets { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CityMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CityMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CityMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown City unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CityMutation) ResetEdge(name string) error { + switch name { + case city.EdgeStreets: + m.ResetStreets() + return nil + } + return fmt.Errorf("unknown City edge %s", name) +} + +// StreetMutation represents an operation that mutate the Streets +// nodes in the graph. +type StreetMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + city *int + clearedcity bool +} + +var _ ent.Mutation = (*StreetMutation)(nil) + +// newStreetMutation creates new mutation for $n.Name. +func newStreetMutation(c config, op Op) *StreetMutation { + return &StreetMutation{ + config: c, + op: op, + typ: TypeStreet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m StreetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m StreetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *StreetMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *StreetMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *StreetMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *StreetMutation) ResetName() { + m.name = nil +} + +// SetCityID sets the city edge to City by id. +func (m *StreetMutation) SetCityID(id int) { + m.city = &id +} + +// ClearCity clears the city edge to City. +func (m *StreetMutation) ClearCity() { + m.clearedcity = true +} + +// CityCleared returns if the edge city was cleared. +func (m *StreetMutation) CityCleared() bool { + return m.clearedcity +} + +// CityID returns the city id in the mutation. +func (m *StreetMutation) CityID() (id int, exists bool) { + if m.city != nil { + return *m.city, true + } + return +} + +// CityIDs returns the city ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// CityID instead. It exists only for internal usage by the builders. +func (m *StreetMutation) CityIDs() (ids []int) { + if id := m.city; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetCity reset all changes of the city edge. +func (m *StreetMutation) ResetCity() { + m.city = nil + m.clearedcity = false +} + +// Op returns the operation name. +func (m *StreetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Street). +func (m *StreetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *StreetMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, street.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *StreetMutation) Field(name string) (ent.Value, bool) { + switch name { + case street.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *StreetMutation) SetField(name string, value ent.Value) error { + switch name { + case street.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Street field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *StreetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *StreetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *StreetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Street numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *StreetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *StreetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *StreetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Street nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *StreetMutation) ResetField(name string) error { + switch name { + case street.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Street field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *StreetMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.city != nil { + edges = append(edges, street.EdgeCity) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *StreetMutation) AddedIDs(name string) []ent.Value { + switch name { + case street.EdgeCity: + if id := m.city; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *StreetMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *StreetMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *StreetMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedcity { + edges = append(edges, street.EdgeCity) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *StreetMutation) EdgeCleared(name string) bool { + switch name { + case street.EdgeCity: + return m.clearedcity + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *StreetMutation) ClearEdge(name string) error { + switch name { + case street.EdgeCity: + m.ClearCity() + return nil + } + return fmt.Errorf("unknown Street unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *StreetMutation) ResetEdge(name string) error { + switch name { + case street.EdgeCity: + m.ResetCity() + return nil + } + return fmt.Errorf("unknown Street edge %s", name) +} diff --git a/examples/edgeindex/ent/privacy/privacy.go b/examples/edgeindex/ent/privacy/privacy.go new file mode 100644 index 000000000..04c05d0c3 --- /dev/null +++ b/examples/edgeindex/ent/privacy/privacy.go @@ -0,0 +1,195 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/edgeindex/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CityReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CityReadRuleFunc func(context.Context, *ent.City) error + +// EvalRead calls f(ctx, v). +func (f CityReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.City); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.City", v) +} + +// The CityWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CityWriteRuleFunc func(context.Context, *ent.CityMutation) error + +// EvalWrite calls f(ctx, m). +func (f CityWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CityMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CityMutation", m) +} + +// The StreetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type StreetReadRuleFunc func(context.Context, *ent.Street) error + +// EvalRead calls f(ctx, v). +func (f StreetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Street); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Street", v) +} + +// The StreetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type StreetWriteRuleFunc func(context.Context, *ent.StreetMutation) error + +// EvalWrite calls f(ctx, m). +func (f StreetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.StreetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.StreetMutation", m) +} diff --git a/examples/edgeindex/ent/runtime.go b/examples/edgeindex/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/edgeindex/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/edgeindex/ent/runtime/runtime.go b/examples/edgeindex/ent/runtime/runtime.go new file mode 100644 index 000000000..4cf8c67d0 --- /dev/null +++ b/examples/edgeindex/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/edgeindex/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/edgeindex/ent/street/street.go b/examples/edgeindex/ent/street/street.go index 0fb47e47d..7079d9c0a 100644 --- a/examples/edgeindex/ent/street/street.go +++ b/examples/edgeindex/ent/street/street.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the street type in the database. Label = "street" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeCity holds the string denoting the city edge name in mutations. + EdgeCity = "city" + // Table holds the table name of the street in the database. Table = "streets" // CityTable is the table the holds the city relation/edge. diff --git a/examples/edgeindex/ent/street_create.go b/examples/edgeindex/ent/street_create.go index 1243a543b..5479e2eb4 100644 --- a/examples/edgeindex/ent/street_create.go +++ b/examples/edgeindex/ent/street_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/edgeindex/ent/city" @@ -19,22 +20,19 @@ import ( // StreetCreate is the builder for creating a Street entity. type StreetCreate struct { config - name *string - city map[int]struct{} + mutation *StreetMutation + hooks []Hook } // SetName sets the name field. func (sc *StreetCreate) SetName(s string) *StreetCreate { - sc.name = &s + sc.mutation.SetName(s) return sc } // SetCityID sets the city edge to City by id. func (sc *StreetCreate) SetCityID(id int) *StreetCreate { - if sc.city == nil { - sc.city = make(map[int]struct{}) - } - sc.city[id] = struct{}{} + sc.mutation.SetCityID(id) return sc } @@ -53,13 +51,33 @@ func (sc *StreetCreate) SetCity(c *City) *StreetCreate { // Save creates the Street in the database. func (sc *StreetCreate) Save(ctx context.Context) (*Street, error) { - if sc.name == nil { + if _, ok := sc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(sc.city) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"city\"") + var ( + err error + node *Street + ) + if len(sc.hooks) == 0 { + node, err = sc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*StreetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + sc.mutation = mutation + node, err = sc.sqlSave(ctx) + return node, err + }) + for i := len(sc.hooks); i > 0; i-- { + mut = sc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, sc.mutation); err != nil { + return nil, err + } } - return sc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -82,15 +100,15 @@ func (sc *StreetCreate) sqlSave(ctx context.Context) (*Street, error) { }, } ) - if value := sc.name; value != nil { + if value, ok := sc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: street.FieldName, }) - s.Name = *value + s.Name = value } - if nodes := sc.city; len(nodes) > 0 { + if nodes := sc.mutation.CityIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -104,7 +122,7 @@ func (sc *StreetCreate) sqlSave(ctx context.Context) (*Street, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/edgeindex/ent/street_delete.go b/examples/edgeindex/ent/street_delete.go index 507204e78..9d67efccd 100644 --- a/examples/edgeindex/ent/street_delete.go +++ b/examples/edgeindex/ent/street_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // StreetDelete is the builder for deleting a Street entity. type StreetDelete struct { config + hooks []Hook + mutation *StreetMutation predicates []predicate.Street } @@ -30,7 +33,30 @@ func (sd *StreetDelete) Where(ps ...predicate.Street) *StreetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (sd *StreetDelete) Exec(ctx context.Context) (int, error) { - return sd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(sd.hooks) == 0 { + affected, err = sd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*StreetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + sd.mutation = mutation + affected, err = sd.sqlExec(ctx) + return affected, err + }) + for i := len(sd.hooks); i > 0; i-- { + mut = sd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, sd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/edgeindex/ent/street_update.go b/examples/edgeindex/ent/street_update.go index f151ddf0a..76858bc64 100644 --- a/examples/edgeindex/ent/street_update.go +++ b/examples/edgeindex/ent/street_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,10 +21,9 @@ import ( // StreetUpdate is the builder for updating Street entities. type StreetUpdate struct { config - name *string - city map[int]struct{} - clearedCity bool - predicates []predicate.Street + hooks []Hook + mutation *StreetMutation + predicates []predicate.Street } // Where adds a new predicate for the builder. @@ -35,16 +34,13 @@ func (su *StreetUpdate) Where(ps ...predicate.Street) *StreetUpdate { // SetName sets the name field. func (su *StreetUpdate) SetName(s string) *StreetUpdate { - su.name = &s + su.mutation.SetName(s) return su } // SetCityID sets the city edge to City by id. func (su *StreetUpdate) SetCityID(id int) *StreetUpdate { - if su.city == nil { - su.city = make(map[int]struct{}) - } - su.city[id] = struct{}{} + su.mutation.SetCityID(id) return su } @@ -63,16 +59,37 @@ func (su *StreetUpdate) SetCity(c *City) *StreetUpdate { // ClearCity clears the city edge to City. func (su *StreetUpdate) ClearCity() *StreetUpdate { - su.clearedCity = true + su.mutation.ClearCity() return su } // Save executes the query and returns the number of rows/vertices matched by this operation. func (su *StreetUpdate) Save(ctx context.Context) (int, error) { - if len(su.city) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"city\"") + + var ( + err error + affected int + ) + if len(su.hooks) == 0 { + affected, err = su.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*StreetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + su.mutation = mutation + affected, err = su.sqlSave(ctx) + return affected, err + }) + for i := len(su.hooks); i > 0; i-- { + mut = su.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, su.mutation); err != nil { + return 0, err + } } - return su.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -115,14 +132,14 @@ func (su *StreetUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := su.name; value != nil { + if value, ok := su.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: street.FieldName, }) } - if su.clearedCity { + if su.mutation.CityCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -138,7 +155,7 @@ func (su *StreetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := su.city; len(nodes) > 0 { + if nodes := su.mutation.CityIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -152,7 +169,7 @@ func (su *StreetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -171,24 +188,19 @@ func (su *StreetUpdate) sqlSave(ctx context.Context) (n int, err error) { // StreetUpdateOne is the builder for updating a single Street entity. type StreetUpdateOne struct { config - id int - name *string - city map[int]struct{} - clearedCity bool + hooks []Hook + mutation *StreetMutation } // SetName sets the name field. func (suo *StreetUpdateOne) SetName(s string) *StreetUpdateOne { - suo.name = &s + suo.mutation.SetName(s) return suo } // SetCityID sets the city edge to City by id. func (suo *StreetUpdateOne) SetCityID(id int) *StreetUpdateOne { - if suo.city == nil { - suo.city = make(map[int]struct{}) - } - suo.city[id] = struct{}{} + suo.mutation.SetCityID(id) return suo } @@ -207,16 +219,37 @@ func (suo *StreetUpdateOne) SetCity(c *City) *StreetUpdateOne { // ClearCity clears the city edge to City. func (suo *StreetUpdateOne) ClearCity() *StreetUpdateOne { - suo.clearedCity = true + suo.mutation.ClearCity() return suo } // Save executes the query and returns the updated entity. func (suo *StreetUpdateOne) Save(ctx context.Context) (*Street, error) { - if len(suo.city) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"city\"") + + var ( + err error + node *Street + ) + if len(suo.hooks) == 0 { + node, err = suo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*StreetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + suo.mutation = mutation + node, err = suo.sqlSave(ctx) + return node, err + }) + for i := len(suo.hooks); i > 0; i-- { + mut = suo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, suo.mutation); err != nil { + return nil, err + } } - return suo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -247,20 +280,24 @@ func (suo *StreetUpdateOne) sqlSave(ctx context.Context) (s *Street, err error) Table: street.Table, Columns: street.Columns, ID: &sqlgraph.FieldSpec{ - Value: suo.id, Type: field.TypeInt, Column: street.FieldID, }, }, } - if value := suo.name; value != nil { + id, ok := suo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Street.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := suo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: street.FieldName, }) } - if suo.clearedCity { + if suo.mutation.CityCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -276,7 +313,7 @@ func (suo *StreetUpdateOne) sqlSave(ctx context.Context) (s *Street, err error) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := suo.city; len(nodes) > 0 { + if nodes := suo.mutation.CityIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -290,7 +327,7 @@ func (suo *StreetUpdateOne) sqlSave(ctx context.Context) (s *Street, err error) }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/edgeindex/ent/tx.go b/examples/edgeindex/ent/tx.go index 3f9f40c45..1997d6b27 100644 --- a/examples/edgeindex/ent/tx.go +++ b/examples/edgeindex/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/edgeindex/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -34,12 +33,14 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - City: NewCityClient(tx.config), - Street: NewStreetClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.City = NewCityClient(tx.config) + tx.Street = NewStreetClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/entcpkg/ent/client.go b/examples/entcpkg/ent/client.go index 777e15f89..4f98b13f8 100644 --- a/examples/entcpkg/ent/client.go +++ b/examples/entcpkg/ent/client.go @@ -30,13 +30,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -64,7 +67,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -82,12 +85,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -95,6 +96,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -105,14 +112,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -122,12 +137,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -137,7 +155,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -158,3 +179,8 @@ func (c *UserClient) GetX(ctx context.Context, id int) *User { } return u } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/entcpkg/ent/config.go b/examples/entcpkg/ent/config.go index dd64c4cf6..379610598 100644 --- a/examples/entcpkg/ent/config.go +++ b/examples/entcpkg/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/entcpkg/ent/ent.go b/examples/entcpkg/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/entcpkg/ent/ent.go +++ b/examples/entcpkg/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/entcpkg/ent/hook/hook.go b/examples/entcpkg/ent/hook/hook.go new file mode 100644 index 000000000..9667f60c9 --- /dev/null +++ b/examples/entcpkg/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/entcpkg/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/entcpkg/ent/mutation.go b/examples/entcpkg/ent/mutation.go new file mode 100644 index 000000000..f76e0c898 --- /dev/null +++ b/examples/entcpkg/ent/mutation.go @@ -0,0 +1,220 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + clearedFields map[string]bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 0) + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/entcpkg/ent/privacy/privacy.go b/examples/entcpkg/ent/privacy/privacy.go new file mode 100644 index 000000000..f6085f7a8 --- /dev/null +++ b/examples/entcpkg/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/entcpkg/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/entcpkg/ent/runtime.go b/examples/entcpkg/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/entcpkg/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/entcpkg/ent/runtime/runtime.go b/examples/entcpkg/ent/runtime/runtime.go new file mode 100644 index 000000000..9de2682c7 --- /dev/null +++ b/examples/entcpkg/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/entcpkg/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/entcpkg/ent/tx.go b/examples/entcpkg/ent/tx.go index 2c1a182df..fe30afd5c 100644 --- a/examples/entcpkg/ent/tx.go +++ b/examples/entcpkg/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/entcpkg/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/entcpkg/ent/user_create.go b/examples/entcpkg/ent/user_create.go index d22df3d1b..d4b3423ad 100644 --- a/examples/entcpkg/ent/user_create.go +++ b/examples/entcpkg/ent/user_create.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/entcpkg/ent/user" @@ -17,11 +18,36 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config + mutation *UserMutation + hooks []Hook } // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. diff --git a/examples/entcpkg/ent/user_delete.go b/examples/entcpkg/ent/user_delete.go index ba7d0f224..83f5b4ff6 100644 --- a/examples/entcpkg/ent/user_delete.go +++ b/examples/entcpkg/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/entcpkg/ent/user_update.go b/examples/entcpkg/ent/user_update.go index 4df99f01d..c8f2e5578 100644 --- a/examples/entcpkg/ent/user_update.go +++ b/examples/entcpkg/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -87,12 +113,36 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int + hooks []Hook + mutation *UserMutation } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -123,12 +173,16 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id u = &User{config: uuo.config} _spec.Assign = u.assignValues _spec.ScanValues = u.scanValues() diff --git a/examples/m2m2types/ent/client.go b/examples/m2m2types/ent/client.go index 48004a7aa..4924f6b63 100644 --- a/examples/m2m2types/ent/client.go +++ b/examples/m2m2types/ent/client.go @@ -34,14 +34,17 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Group: NewGroupClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Group = NewGroupClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -69,7 +72,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Group: NewGroupClient(cfg), @@ -88,13 +91,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Group: NewGroupClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -102,6 +102,13 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Group.Use(hooks...) + c.User.Use(hooks...) +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -112,14 +119,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -129,12 +144,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id int) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -144,7 +162,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id int) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -180,6 +201,11 @@ func (c *GroupClient) QueryUsers(gr *Group) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -190,14 +216,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -207,12 +241,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -222,7 +259,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -257,3 +297,8 @@ func (c *UserClient) QueryGroups(u *User) *GroupQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/m2m2types/ent/config.go b/examples/m2m2types/ent/config.go index dd64c4cf6..7cf624298 100644 --- a/examples/m2m2types/ent/config.go +++ b/examples/m2m2types/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,14 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Group []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/m2m2types/ent/ent.go b/examples/m2m2types/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/m2m2types/ent/ent.go +++ b/examples/m2m2types/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/m2m2types/ent/group/group.go b/examples/m2m2types/ent/group/group.go index 070d4f894..6be43c55d 100644 --- a/examples/m2m2types/ent/group/group.go +++ b/examples/m2m2types/ent/group/group.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the group type in the database. Label = "group" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // Table holds the table name of the group in the database. Table = "groups" // UsersTable is the table the holds the users relation/edge. The primary key declared below. diff --git a/examples/m2m2types/ent/group_create.go b/examples/m2m2types/ent/group_create.go index f4c515a50..128c4f9c3 100644 --- a/examples/m2m2types/ent/group_create.go +++ b/examples/m2m2types/ent/group_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/m2m2types/ent/group" @@ -19,24 +20,19 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - name *string - users map[int]struct{} + mutation *GroupMutation + hooks []Hook } // SetName sets the name field. func (gc *GroupCreate) SetName(s string) *GroupCreate { - gc.name = &s + gc.mutation.SetName(s) return gc } // AddUserIDs adds the users edge to User by ids. func (gc *GroupCreate) AddUserIDs(ids ...int) *GroupCreate { - if gc.users == nil { - gc.users = make(map[int]struct{}) - } - for i := range ids { - gc.users[ids[i]] = struct{}{} - } + gc.mutation.AddUserIDs(ids...) return gc } @@ -51,10 +47,33 @@ func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - if gc.name == nil { + if _, ok := gc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return gc.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -77,15 +96,15 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, } ) - if value := gc.name; value != nil { + if value, ok := gc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) - gr.Name = *value + gr.Name = value } - if nodes := gc.users; len(nodes) > 0 { + if nodes := gc.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -99,7 +118,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/m2m2types/ent/group_delete.go b/examples/m2m2types/ent/group_delete.go index 988063367..0255e29e5 100644 --- a/examples/m2m2types/ent/group_delete.go +++ b/examples/m2m2types/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/m2m2types/ent/group_update.go b/examples/m2m2types/ent/group_update.go index 2bdf84a04..8d5e54d51 100644 --- a/examples/m2m2types/ent/group_update.go +++ b/examples/m2m2types/ent/group_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,10 +21,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - name *string - users map[int]struct{} - removedUsers map[int]struct{} - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -34,18 +34,13 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // SetName sets the name field. func (gu *GroupUpdate) SetName(s string) *GroupUpdate { - gu.name = &s + gu.mutation.SetName(s) return gu } // AddUserIDs adds the users edge to User by ids. func (gu *GroupUpdate) AddUserIDs(ids ...int) *GroupUpdate { - if gu.users == nil { - gu.users = make(map[int]struct{}) - } - for i := range ids { - gu.users[ids[i]] = struct{}{} - } + gu.mutation.AddUserIDs(ids...) return gu } @@ -60,12 +55,7 @@ func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { // RemoveUserIDs removes the users edge to User by ids. func (gu *GroupUpdate) RemoveUserIDs(ids ...int) *GroupUpdate { - if gu.removedUsers == nil { - gu.removedUsers = make(map[int]struct{}) - } - for i := range ids { - gu.removedUsers[ids[i]] = struct{}{} - } + gu.mutation.RemoveUserIDs(ids...) return gu } @@ -80,7 +70,31 @@ func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - return gu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -123,14 +137,14 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := gu.name; value != nil { + if value, ok := gu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := gu.removedUsers; len(nodes) > 0 { + if nodes := gu.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -144,12 +158,12 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.users; len(nodes) > 0 { + if nodes := gu.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -163,7 +177,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -182,26 +196,19 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id int - name *string - users map[int]struct{} - removedUsers map[int]struct{} + hooks []Hook + mutation *GroupMutation } // SetName sets the name field. func (guo *GroupUpdateOne) SetName(s string) *GroupUpdateOne { - guo.name = &s + guo.mutation.SetName(s) return guo } // AddUserIDs adds the users edge to User by ids. func (guo *GroupUpdateOne) AddUserIDs(ids ...int) *GroupUpdateOne { - if guo.users == nil { - guo.users = make(map[int]struct{}) - } - for i := range ids { - guo.users[ids[i]] = struct{}{} - } + guo.mutation.AddUserIDs(ids...) return guo } @@ -216,12 +223,7 @@ func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { // RemoveUserIDs removes the users edge to User by ids. func (guo *GroupUpdateOne) RemoveUserIDs(ids ...int) *GroupUpdateOne { - if guo.removedUsers == nil { - guo.removedUsers = make(map[int]struct{}) - } - for i := range ids { - guo.removedUsers[ids[i]] = struct{}{} - } + guo.mutation.RemoveUserIDs(ids...) return guo } @@ -236,7 +238,31 @@ func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - return guo.sqlSave(ctx) + + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -267,20 +293,24 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeInt, Column: group.FieldID, }, }, } - if value := guo.name; value != nil { + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := guo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := guo.removedUsers; len(nodes) > 0 { + if nodes := guo.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -294,12 +324,12 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.users; len(nodes) > 0 { + if nodes := guo.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -313,7 +343,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/m2m2types/ent/hook/hook.go b/examples/m2m2types/ent/hook/hook.go new file mode 100644 index 000000000..d3edc9dcc --- /dev/null +++ b/examples/m2m2types/ent/hook/hook.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/m2m2types/ent" +) + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/m2m2types/ent/mutation.go b/examples/m2m2types/ent/mutation.go new file mode 100644 index 000000000..8731ae50a --- /dev/null +++ b/examples/m2m2types/ent/mutation.go @@ -0,0 +1,693 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/m2m2types/ent/group" + "github.com/facebookincubator/ent/examples/m2m2types/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeGroup = "Group" + TypeUser = "User" +) + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + users map[int]struct{} + removedusers map[int]struct{} +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *GroupMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *GroupMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *GroupMutation) ResetName() { + m.name = nil +} + +// AddUserIDs adds the users edge to User by ids. +func (m *GroupMutation) AddUserIDs(ids ...int) { + if m.users == nil { + m.users = make(map[int]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// RemoveUserIDs removes the users edge to User by ids. +func (m *GroupMutation) RemoveUserIDs(ids ...int) { + if m.removedusers == nil { + m.removedusers = make(map[int]struct{}) + } + for i := range ids { + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed ids of users. +func (m *GroupMutation) RemovedUsersIDs() (ids []int) { + for id := range m.removedusers { + ids = append(ids, id) + } + return +} + +// UsersIDs returns the users ids in the mutation. +func (m *GroupMutation) UsersIDs() (ids []int) { + for id := range m.users { + ids = append(ids, id) + } + return +} + +// ResetUsers reset all changes of the users edge. +func (m *GroupMutation) ResetUsers() { + m.users = nil + m.removedusers = nil +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, group.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + case group.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + case group.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + case group.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.users != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedusers != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + case group.EdgeUsers: + m.ResetUsers() + return nil + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + groups map[int]struct{} + removedgroups map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *UserMutation) AddGroupIDs(ids ...int) { + if m.groups == nil { + m.groups = make(map[int]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *UserMutation) RemoveGroupIDs(ids ...int) { + if m.removedgroups == nil { + m.removedgroups = make(map[int]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *UserMutation) RemovedGroupsIDs() (ids []int) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *UserMutation) GroupsIDs() (ids []int) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *UserMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.groups != nil { + edges = append(edges, user.EdgeGroups) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedgroups != nil { + edges = append(edges, user.EdgeGroups) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeGroups: + m.ResetGroups() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/m2m2types/ent/privacy/privacy.go b/examples/m2m2types/ent/privacy/privacy.go new file mode 100644 index 000000000..8fe06b324 --- /dev/null +++ b/examples/m2m2types/ent/privacy/privacy.go @@ -0,0 +1,195 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/m2m2types/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/m2m2types/ent/runtime.go b/examples/m2m2types/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/m2m2types/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/m2m2types/ent/runtime/runtime.go b/examples/m2m2types/ent/runtime/runtime.go new file mode 100644 index 000000000..ea2c95466 --- /dev/null +++ b/examples/m2m2types/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/m2m2types/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/m2m2types/ent/tx.go b/examples/m2m2types/ent/tx.go index b39001fec..d8af1c483 100644 --- a/examples/m2m2types/ent/tx.go +++ b/examples/m2m2types/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/m2m2types/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -34,12 +33,14 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Group: NewGroupClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Group = NewGroupClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/m2m2types/ent/user/user.go b/examples/m2m2types/ent/user/user.go index d743d1702..75c34e60b 100644 --- a/examples/m2m2types/ent/user/user.go +++ b/examples/m2m2types/ent/user/user.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // Table holds the table name of the user in the database. Table = "users" // GroupsTable is the table the holds the groups relation/edge. The primary key declared below. diff --git a/examples/m2m2types/ent/user_create.go b/examples/m2m2types/ent/user_create.go index 9c45c91da..8c0be9e22 100644 --- a/examples/m2m2types/ent/user_create.go +++ b/examples/m2m2types/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/m2m2types/ent/group" @@ -19,31 +20,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - groups map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // AddGroupIDs adds the groups edge to Group by ids. func (uc *UserCreate) AddGroupIDs(ids ...int) *UserCreate { - if uc.groups == nil { - uc.groups = make(map[int]struct{}) - } - for i := range ids { - uc.groups[ids[i]] = struct{}{} - } + uc.mutation.AddGroupIDs(ids...) return uc } @@ -58,13 +53,36 @@ func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -87,23 +105,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.groups; len(nodes) > 0 { + if nodes := uc.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -117,7 +135,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/m2m2types/ent/user_delete.go b/examples/m2m2types/ent/user_delete.go index f73980d97..406a96e59 100644 --- a/examples/m2m2types/ent/user_delete.go +++ b/examples/m2m2types/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/m2m2types/ent/user_update.go b/examples/m2m2types/ent/user_update.go index 6ee8302b6..76445a540 100644 --- a/examples/m2m2types/ent/user_update.go +++ b/examples/m2m2types/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,12 +21,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - groups map[int]struct{} - removedGroups map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -36,35 +34,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // AddGroupIDs adds the groups edge to Group by ids. func (uu *UserUpdate) AddGroupIDs(ids ...int) *UserUpdate { - if uu.groups == nil { - uu.groups = make(map[int]struct{}) - } - for i := range ids { - uu.groups[ids[i]] = struct{}{} - } + uu.mutation.AddGroupIDs(ids...) return uu } @@ -79,12 +68,7 @@ func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (uu *UserUpdate) RemoveGroupIDs(ids ...int) *UserUpdate { - if uu.removedGroups == nil { - uu.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uu.removedGroups[ids[i]] = struct{}{} - } + uu.mutation.RemoveGroupIDs(ids...) return uu } @@ -99,7 +83,31 @@ func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -142,28 +150,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedGroups; len(nodes) > 0 { + if nodes := uu.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -177,12 +185,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.groups; len(nodes) > 0 { + if nodes := uu.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -196,7 +204,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -215,45 +223,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - groups map[int]struct{} - removedGroups map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // AddGroupIDs adds the groups edge to Group by ids. func (uuo *UserUpdateOne) AddGroupIDs(ids ...int) *UserUpdateOne { - if uuo.groups == nil { - uuo.groups = make(map[int]struct{}) - } - for i := range ids { - uuo.groups[ids[i]] = struct{}{} - } + uuo.mutation.AddGroupIDs(ids...) return uuo } @@ -268,12 +263,7 @@ func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...int) *UserUpdateOne { - if uuo.removedGroups == nil { - uuo.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uuo.removedGroups[ids[i]] = struct{}{} - } + uuo.mutation.RemoveGroupIDs(ids...) return uuo } @@ -288,7 +278,31 @@ func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -319,34 +333,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedGroups; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -360,12 +378,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.groups; len(nodes) > 0 { + if nodes := uuo.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -379,7 +397,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/m2mbidi/ent/client.go b/examples/m2mbidi/ent/client.go index 4818260d7..780c13ff3 100644 --- a/examples/m2mbidi/ent/client.go +++ b/examples/m2mbidi/ent/client.go @@ -31,13 +31,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -65,7 +68,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -83,12 +86,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -96,6 +97,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -106,14 +113,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -123,12 +138,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -138,7 +156,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -173,3 +194,8 @@ func (c *UserClient) QueryFriends(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/m2mbidi/ent/config.go b/examples/m2mbidi/ent/config.go index dd64c4cf6..379610598 100644 --- a/examples/m2mbidi/ent/config.go +++ b/examples/m2mbidi/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/m2mbidi/ent/ent.go b/examples/m2mbidi/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/m2mbidi/ent/ent.go +++ b/examples/m2mbidi/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/m2mbidi/ent/hook/hook.go b/examples/m2mbidi/ent/hook/hook.go new file mode 100644 index 000000000..ba9b9f768 --- /dev/null +++ b/examples/m2mbidi/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/m2mbidi/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/m2mbidi/ent/mutation.go b/examples/m2mbidi/ent/mutation.go new file mode 100644 index 000000000..8148f8ea1 --- /dev/null +++ b/examples/m2mbidi/ent/mutation.go @@ -0,0 +1,394 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/m2mbidi/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + friends map[int]struct{} + removedfriends map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddFriendIDs adds the friends edge to User by ids. +func (m *UserMutation) AddFriendIDs(ids ...int) { + if m.friends == nil { + m.friends = make(map[int]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (m *UserMutation) RemoveFriendIDs(ids ...int) { + if m.removedfriends == nil { + m.removedfriends = make(map[int]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *UserMutation) RemovedFriendsIDs() (ids []int) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *UserMutation) FriendsIDs() (ids []int) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *UserMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.friends != nil { + edges = append(edges, user.EdgeFriends) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedfriends != nil { + edges = append(edges, user.EdgeFriends) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeFriends: + m.ResetFriends() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/m2mbidi/ent/privacy/privacy.go b/examples/m2mbidi/ent/privacy/privacy.go new file mode 100644 index 000000000..ecea900c9 --- /dev/null +++ b/examples/m2mbidi/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/m2mbidi/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/m2mbidi/ent/runtime.go b/examples/m2mbidi/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/m2mbidi/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/m2mbidi/ent/runtime/runtime.go b/examples/m2mbidi/ent/runtime/runtime.go new file mode 100644 index 000000000..fd8198e16 --- /dev/null +++ b/examples/m2mbidi/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/m2mbidi/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/m2mbidi/ent/tx.go b/examples/m2mbidi/ent/tx.go index 6399a6859..fe30afd5c 100644 --- a/examples/m2mbidi/ent/tx.go +++ b/examples/m2mbidi/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/m2mbidi/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/m2mbidi/ent/user/user.go b/examples/m2mbidi/ent/user/user.go index 59abaa60c..ff2759c74 100644 --- a/examples/m2mbidi/ent/user/user.go +++ b/examples/m2mbidi/ent/user/user.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // Table holds the table name of the user in the database. Table = "users" // FriendsTable is the table the holds the friends relation/edge. The primary key declared below. diff --git a/examples/m2mbidi/ent/user_create.go b/examples/m2mbidi/ent/user_create.go index 8bf509d1c..312279b8f 100644 --- a/examples/m2mbidi/ent/user_create.go +++ b/examples/m2mbidi/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/m2mbidi/ent/user" @@ -18,31 +19,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - friends map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // AddFriendIDs adds the friends edge to User by ids. func (uc *UserCreate) AddFriendIDs(ids ...int) *UserCreate { - if uc.friends == nil { - uc.friends = make(map[int]struct{}) - } - for i := range ids { - uc.friends[ids[i]] = struct{}{} - } + uc.mutation.AddFriendIDs(ids...) return uc } @@ -57,13 +52,36 @@ func (uc *UserCreate) AddFriends(u ...*User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -86,23 +104,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.friends; len(nodes) > 0 { + if nodes := uc.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -116,7 +134,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/m2mbidi/ent/user_delete.go b/examples/m2mbidi/ent/user_delete.go index 54a5cca7a..1677db391 100644 --- a/examples/m2mbidi/ent/user_delete.go +++ b/examples/m2mbidi/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/m2mbidi/ent/user_update.go b/examples/m2mbidi/ent/user_update.go index 9a33549d9..953e84a19 100644 --- a/examples/m2mbidi/ent/user_update.go +++ b/examples/m2mbidi/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,12 +20,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - friends map[int]struct{} - removedFriends map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -35,35 +33,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // AddFriendIDs adds the friends edge to User by ids. func (uu *UserUpdate) AddFriendIDs(ids ...int) *UserUpdate { - if uu.friends == nil { - uu.friends = make(map[int]struct{}) - } - for i := range ids { - uu.friends[ids[i]] = struct{}{} - } + uu.mutation.AddFriendIDs(ids...) return uu } @@ -78,12 +67,7 @@ func (uu *UserUpdate) AddFriends(u ...*User) *UserUpdate { // RemoveFriendIDs removes the friends edge to User by ids. func (uu *UserUpdate) RemoveFriendIDs(ids ...int) *UserUpdate { - if uu.removedFriends == nil { - uu.removedFriends = make(map[int]struct{}) - } - for i := range ids { - uu.removedFriends[ids[i]] = struct{}{} - } + uu.mutation.RemoveFriendIDs(ids...) return uu } @@ -98,7 +82,31 @@ func (uu *UserUpdate) RemoveFriends(u ...*User) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -141,28 +149,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedFriends; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -176,12 +184,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.friends; len(nodes) > 0 { + if nodes := uu.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -195,7 +203,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -214,45 +222,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - friends map[int]struct{} - removedFriends map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // AddFriendIDs adds the friends edge to User by ids. func (uuo *UserUpdateOne) AddFriendIDs(ids ...int) *UserUpdateOne { - if uuo.friends == nil { - uuo.friends = make(map[int]struct{}) - } - for i := range ids { - uuo.friends[ids[i]] = struct{}{} - } + uuo.mutation.AddFriendIDs(ids...) return uuo } @@ -267,12 +262,7 @@ func (uuo *UserUpdateOne) AddFriends(u ...*User) *UserUpdateOne { // RemoveFriendIDs removes the friends edge to User by ids. func (uuo *UserUpdateOne) RemoveFriendIDs(ids ...int) *UserUpdateOne { - if uuo.removedFriends == nil { - uuo.removedFriends = make(map[int]struct{}) - } - for i := range ids { - uuo.removedFriends[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFriendIDs(ids...) return uuo } @@ -287,7 +277,31 @@ func (uuo *UserUpdateOne) RemoveFriends(u ...*User) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -318,34 +332,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedFriends; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -359,12 +377,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.friends; len(nodes) > 0 { + if nodes := uuo.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -378,7 +396,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/m2mrecur/ent/client.go b/examples/m2mrecur/ent/client.go index 1094693f4..e1402da1f 100644 --- a/examples/m2mrecur/ent/client.go +++ b/examples/m2mrecur/ent/client.go @@ -31,13 +31,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -65,7 +68,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -83,12 +86,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -96,6 +97,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -106,14 +113,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -123,12 +138,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -138,7 +156,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -187,3 +208,8 @@ func (c *UserClient) QueryFollowing(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/m2mrecur/ent/config.go b/examples/m2mrecur/ent/config.go index dd64c4cf6..379610598 100644 --- a/examples/m2mrecur/ent/config.go +++ b/examples/m2mrecur/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/m2mrecur/ent/ent.go b/examples/m2mrecur/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/m2mrecur/ent/ent.go +++ b/examples/m2mrecur/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/m2mrecur/ent/hook/hook.go b/examples/m2mrecur/ent/hook/hook.go new file mode 100644 index 000000000..c8ed3cc49 --- /dev/null +++ b/examples/m2mrecur/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/m2mrecur/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/m2mrecur/ent/mutation.go b/examples/m2mrecur/ent/mutation.go new file mode 100644 index 000000000..b9ae33eaa --- /dev/null +++ b/examples/m2mrecur/ent/mutation.go @@ -0,0 +1,459 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/m2mrecur/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + followers map[int]struct{} + removedfollowers map[int]struct{} + following map[int]struct{} + removedfollowing map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddFollowerIDs adds the followers edge to User by ids. +func (m *UserMutation) AddFollowerIDs(ids ...int) { + if m.followers == nil { + m.followers = make(map[int]struct{}) + } + for i := range ids { + m.followers[ids[i]] = struct{}{} + } +} + +// RemoveFollowerIDs removes the followers edge to User by ids. +func (m *UserMutation) RemoveFollowerIDs(ids ...int) { + if m.removedfollowers == nil { + m.removedfollowers = make(map[int]struct{}) + } + for i := range ids { + m.removedfollowers[ids[i]] = struct{}{} + } +} + +// RemovedFollowers returns the removed ids of followers. +func (m *UserMutation) RemovedFollowersIDs() (ids []int) { + for id := range m.removedfollowers { + ids = append(ids, id) + } + return +} + +// FollowersIDs returns the followers ids in the mutation. +func (m *UserMutation) FollowersIDs() (ids []int) { + for id := range m.followers { + ids = append(ids, id) + } + return +} + +// ResetFollowers reset all changes of the followers edge. +func (m *UserMutation) ResetFollowers() { + m.followers = nil + m.removedfollowers = nil +} + +// AddFollowingIDs adds the following edge to User by ids. +func (m *UserMutation) AddFollowingIDs(ids ...int) { + if m.following == nil { + m.following = make(map[int]struct{}) + } + for i := range ids { + m.following[ids[i]] = struct{}{} + } +} + +// RemoveFollowingIDs removes the following edge to User by ids. +func (m *UserMutation) RemoveFollowingIDs(ids ...int) { + if m.removedfollowing == nil { + m.removedfollowing = make(map[int]struct{}) + } + for i := range ids { + m.removedfollowing[ids[i]] = struct{}{} + } +} + +// RemovedFollowing returns the removed ids of following. +func (m *UserMutation) RemovedFollowingIDs() (ids []int) { + for id := range m.removedfollowing { + ids = append(ids, id) + } + return +} + +// FollowingIDs returns the following ids in the mutation. +func (m *UserMutation) FollowingIDs() (ids []int) { + for id := range m.following { + ids = append(ids, id) + } + return +} + +// ResetFollowing reset all changes of the following edge. +func (m *UserMutation) ResetFollowing() { + m.following = nil + m.removedfollowing = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.followers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.following != nil { + edges = append(edges, user.EdgeFollowing) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.followers)) + for id := range m.followers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.following)) + for id := range m.following { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedfollowers != nil { + edges = append(edges, user.EdgeFollowers) + } + if m.removedfollowing != nil { + edges = append(edges, user.EdgeFollowing) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeFollowers: + ids := make([]ent.Value, 0, len(m.removedfollowers)) + for id := range m.removedfollowers { + ids = append(ids, id) + } + return ids + case user.EdgeFollowing: + ids := make([]ent.Value, 0, len(m.removedfollowing)) + for id := range m.removedfollowing { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeFollowers: + m.ResetFollowers() + return nil + case user.EdgeFollowing: + m.ResetFollowing() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/m2mrecur/ent/privacy/privacy.go b/examples/m2mrecur/ent/privacy/privacy.go new file mode 100644 index 000000000..82089606e --- /dev/null +++ b/examples/m2mrecur/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/m2mrecur/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/m2mrecur/ent/runtime.go b/examples/m2mrecur/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/m2mrecur/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/m2mrecur/ent/runtime/runtime.go b/examples/m2mrecur/ent/runtime/runtime.go new file mode 100644 index 000000000..0dcec7b66 --- /dev/null +++ b/examples/m2mrecur/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/m2mrecur/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/m2mrecur/ent/tx.go b/examples/m2mrecur/ent/tx.go index d32b58182..fe30afd5c 100644 --- a/examples/m2mrecur/ent/tx.go +++ b/examples/m2mrecur/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/m2mrecur/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/m2mrecur/ent/user/user.go b/examples/m2mrecur/ent/user/user.go index 5cff95ba0..0e36f19a4 100644 --- a/examples/m2mrecur/ent/user/user.go +++ b/examples/m2mrecur/ent/user/user.go @@ -10,12 +10,15 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeFollowers holds the string denoting the followers edge name in mutations. + EdgeFollowers = "followers" + // EdgeFollowing holds the string denoting the following edge name in mutations. + EdgeFollowing = "following" + // Table holds the table name of the user in the database. Table = "users" // FollowersTable is the table the holds the followers relation/edge. The primary key declared below. diff --git a/examples/m2mrecur/ent/user_create.go b/examples/m2mrecur/ent/user_create.go index 062ec99e3..dd7a32e48 100644 --- a/examples/m2mrecur/ent/user_create.go +++ b/examples/m2mrecur/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/m2mrecur/ent/user" @@ -18,32 +19,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - followers map[int]struct{} - following map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // AddFollowerIDs adds the followers edge to User by ids. func (uc *UserCreate) AddFollowerIDs(ids ...int) *UserCreate { - if uc.followers == nil { - uc.followers = make(map[int]struct{}) - } - for i := range ids { - uc.followers[ids[i]] = struct{}{} - } + uc.mutation.AddFollowerIDs(ids...) return uc } @@ -58,12 +52,7 @@ func (uc *UserCreate) AddFollowers(u ...*User) *UserCreate { // AddFollowingIDs adds the following edge to User by ids. func (uc *UserCreate) AddFollowingIDs(ids ...int) *UserCreate { - if uc.following == nil { - uc.following = make(map[int]struct{}) - } - for i := range ids { - uc.following[ids[i]] = struct{}{} - } + uc.mutation.AddFollowingIDs(ids...) return uc } @@ -78,13 +67,36 @@ func (uc *UserCreate) AddFollowing(u ...*User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -107,23 +119,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.followers; len(nodes) > 0 { + if nodes := uc.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -137,12 +149,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.following; len(nodes) > 0 { + if nodes := uc.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -156,7 +168,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/m2mrecur/ent/user_delete.go b/examples/m2mrecur/ent/user_delete.go index f1a31f8e7..b203039c5 100644 --- a/examples/m2mrecur/ent/user_delete.go +++ b/examples/m2mrecur/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/m2mrecur/ent/user_update.go b/examples/m2mrecur/ent/user_update.go index 6f2c0d536..0caeedd13 100644 --- a/examples/m2mrecur/ent/user_update.go +++ b/examples/m2mrecur/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,14 +20,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - followers map[int]struct{} - following map[int]struct{} - removedFollowers map[int]struct{} - removedFollowing map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -37,35 +33,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // AddFollowerIDs adds the followers edge to User by ids. func (uu *UserUpdate) AddFollowerIDs(ids ...int) *UserUpdate { - if uu.followers == nil { - uu.followers = make(map[int]struct{}) - } - for i := range ids { - uu.followers[ids[i]] = struct{}{} - } + uu.mutation.AddFollowerIDs(ids...) return uu } @@ -80,12 +67,7 @@ func (uu *UserUpdate) AddFollowers(u ...*User) *UserUpdate { // AddFollowingIDs adds the following edge to User by ids. func (uu *UserUpdate) AddFollowingIDs(ids ...int) *UserUpdate { - if uu.following == nil { - uu.following = make(map[int]struct{}) - } - for i := range ids { - uu.following[ids[i]] = struct{}{} - } + uu.mutation.AddFollowingIDs(ids...) return uu } @@ -100,12 +82,7 @@ func (uu *UserUpdate) AddFollowing(u ...*User) *UserUpdate { // RemoveFollowerIDs removes the followers edge to User by ids. func (uu *UserUpdate) RemoveFollowerIDs(ids ...int) *UserUpdate { - if uu.removedFollowers == nil { - uu.removedFollowers = make(map[int]struct{}) - } - for i := range ids { - uu.removedFollowers[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowerIDs(ids...) return uu } @@ -120,12 +97,7 @@ func (uu *UserUpdate) RemoveFollowers(u ...*User) *UserUpdate { // RemoveFollowingIDs removes the following edge to User by ids. func (uu *UserUpdate) RemoveFollowingIDs(ids ...int) *UserUpdate { - if uu.removedFollowing == nil { - uu.removedFollowing = make(map[int]struct{}) - } - for i := range ids { - uu.removedFollowing[ids[i]] = struct{}{} - } + uu.mutation.RemoveFollowingIDs(ids...) return uu } @@ -140,7 +112,31 @@ func (uu *UserUpdate) RemoveFollowing(u ...*User) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -183,28 +179,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedFollowers; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -218,12 +214,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.followers; len(nodes) > 0 { + if nodes := uu.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -237,12 +233,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFollowing; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -256,12 +252,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.following; len(nodes) > 0 { + if nodes := uu.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -275,7 +271,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -294,47 +290,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - followers map[int]struct{} - following map[int]struct{} - removedFollowers map[int]struct{} - removedFollowing map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // AddFollowerIDs adds the followers edge to User by ids. func (uuo *UserUpdateOne) AddFollowerIDs(ids ...int) *UserUpdateOne { - if uuo.followers == nil { - uuo.followers = make(map[int]struct{}) - } - for i := range ids { - uuo.followers[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowerIDs(ids...) return uuo } @@ -349,12 +330,7 @@ func (uuo *UserUpdateOne) AddFollowers(u ...*User) *UserUpdateOne { // AddFollowingIDs adds the following edge to User by ids. func (uuo *UserUpdateOne) AddFollowingIDs(ids ...int) *UserUpdateOne { - if uuo.following == nil { - uuo.following = make(map[int]struct{}) - } - for i := range ids { - uuo.following[ids[i]] = struct{}{} - } + uuo.mutation.AddFollowingIDs(ids...) return uuo } @@ -369,12 +345,7 @@ func (uuo *UserUpdateOne) AddFollowing(u ...*User) *UserUpdateOne { // RemoveFollowerIDs removes the followers edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowerIDs(ids ...int) *UserUpdateOne { - if uuo.removedFollowers == nil { - uuo.removedFollowers = make(map[int]struct{}) - } - for i := range ids { - uuo.removedFollowers[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowerIDs(ids...) return uuo } @@ -389,12 +360,7 @@ func (uuo *UserUpdateOne) RemoveFollowers(u ...*User) *UserUpdateOne { // RemoveFollowingIDs removes the following edge to User by ids. func (uuo *UserUpdateOne) RemoveFollowingIDs(ids ...int) *UserUpdateOne { - if uuo.removedFollowing == nil { - uuo.removedFollowing = make(map[int]struct{}) - } - for i := range ids { - uuo.removedFollowing[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFollowingIDs(ids...) return uuo } @@ -409,7 +375,31 @@ func (uuo *UserUpdateOne) RemoveFollowing(u ...*User) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -440,34 +430,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedFollowers; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -481,12 +475,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.followers; len(nodes) > 0 { + if nodes := uuo.mutation.FollowersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -500,12 +494,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFollowing; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -519,12 +513,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.following; len(nodes) > 0 { + if nodes := uuo.mutation.FollowingIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -538,7 +532,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2m2types/ent/client.go b/examples/o2m2types/ent/client.go index e4f8da652..20fda3259 100644 --- a/examples/o2m2types/ent/client.go +++ b/examples/o2m2types/ent/client.go @@ -34,14 +34,17 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Pet: NewPetClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Pet = NewPetClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -69,7 +72,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Pet: NewPetClient(cfg), @@ -88,13 +91,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Pet: NewPetClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -102,6 +102,13 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Pet.Use(hooks...) + c.User.Use(hooks...) +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -112,14 +119,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -129,12 +144,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id int) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -144,7 +162,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id int) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -180,6 +201,11 @@ func (c *PetClient) QueryOwner(pe *Pet) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -190,14 +216,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -207,12 +241,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -222,7 +259,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -257,3 +297,8 @@ func (c *UserClient) QueryPets(u *User) *PetQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/o2m2types/ent/config.go b/examples/o2m2types/ent/config.go index dd64c4cf6..61c5e9ec3 100644 --- a/examples/o2m2types/ent/config.go +++ b/examples/o2m2types/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,14 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Pet []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/o2m2types/ent/ent.go b/examples/o2m2types/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/o2m2types/ent/ent.go +++ b/examples/o2m2types/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/o2m2types/ent/hook/hook.go b/examples/o2m2types/ent/hook/hook.go new file mode 100644 index 000000000..2af05b279 --- /dev/null +++ b/examples/o2m2types/ent/hook/hook.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/o2m2types/ent" +) + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/o2m2types/ent/mutation.go b/examples/o2m2types/ent/mutation.go new file mode 100644 index 000000000..2501f216a --- /dev/null +++ b/examples/o2m2types/ent/mutation.go @@ -0,0 +1,687 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/o2m2types/ent/pet" + "github.com/facebookincubator/ent/examples/o2m2types/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypePet = "Pet" + TypeUser = "User" +) + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *PetMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *PetMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *PetMutation) ResetName() { + m.name = nil +} + +// SetOwnerID sets the owner edge to User by id. +func (m *PetMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *PetMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *PetMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *PetMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *PetMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *PetMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, pet.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + case pet.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + case pet.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + case pet.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + case pet.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + case pet.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + pets map[int]struct{} + removedpets map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddPetIDs adds the pets edge to Pet by ids. +func (m *UserMutation) AddPetIDs(ids ...int) { + if m.pets == nil { + m.pets = make(map[int]struct{}) + } + for i := range ids { + m.pets[ids[i]] = struct{}{} + } +} + +// RemovePetIDs removes the pets edge to Pet by ids. +func (m *UserMutation) RemovePetIDs(ids ...int) { + if m.removedpets == nil { + m.removedpets = make(map[int]struct{}) + } + for i := range ids { + m.removedpets[ids[i]] = struct{}{} + } +} + +// RemovedPets returns the removed ids of pets. +func (m *UserMutation) RemovedPetsIDs() (ids []int) { + for id := range m.removedpets { + ids = append(ids, id) + } + return +} + +// PetsIDs returns the pets ids in the mutation. +func (m *UserMutation) PetsIDs() (ids []int) { + for id := range m.pets { + ids = append(ids, id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.removedpets = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.pets)) + for id := range m.pets { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedpets != nil { + edges = append(edges, user.EdgePets) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.removedpets)) + for id := range m.removedpets { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgePets: + m.ResetPets() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/o2m2types/ent/pet/pet.go b/examples/o2m2types/ent/pet/pet.go index f076e3306..01d185ccb 100644 --- a/examples/o2m2types/ent/pet/pet.go +++ b/examples/o2m2types/ent/pet/pet.go @@ -10,10 +10,12 @@ const ( // Label holds the string label denoting the pet type in the database. Label = "pet" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the pet in the database. Table = "pets" // OwnerTable is the table the holds the owner relation/edge. diff --git a/examples/o2m2types/ent/pet_create.go b/examples/o2m2types/ent/pet_create.go index a42f03b1a..e113097fb 100644 --- a/examples/o2m2types/ent/pet_create.go +++ b/examples/o2m2types/ent/pet_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/o2m2types/ent/pet" @@ -19,22 +20,19 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - name *string - owner map[int]struct{} + mutation *PetMutation + hooks []Hook } // SetName sets the name field. func (pc *PetCreate) SetName(s string) *PetCreate { - pc.name = &s + pc.mutation.SetName(s) return pc } // SetOwnerID sets the owner edge to User by id. func (pc *PetCreate) SetOwnerID(id int) *PetCreate { - if pc.owner == nil { - pc.owner = make(map[int]struct{}) - } - pc.owner[id] = struct{}{} + pc.mutation.SetOwnerID(id) return pc } @@ -53,13 +51,33 @@ func (pc *PetCreate) SetOwner(u *User) *PetCreate { // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - if pc.name == nil { + if _, ok := pc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(pc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } } - return pc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -82,15 +100,15 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, } ) - if value := pc.name; value != nil { + if value, ok := pc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) - pe.Name = *value + pe.Name = value } - if nodes := pc.owner; len(nodes) > 0 { + if nodes := pc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -104,7 +122,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2m2types/ent/pet_delete.go b/examples/o2m2types/ent/pet_delete.go index 50b11509e..e6cb1b2a8 100644 --- a/examples/o2m2types/ent/pet_delete.go +++ b/examples/o2m2types/ent/pet_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2m2types/ent/pet_update.go b/examples/o2m2types/ent/pet_update.go index f76e367ee..ae6ba3031 100644 --- a/examples/o2m2types/ent/pet_update.go +++ b/examples/o2m2types/ent/pet_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,10 +21,9 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - name *string - owner map[int]struct{} - clearedOwner bool - predicates []predicate.Pet + hooks []Hook + mutation *PetMutation + predicates []predicate.Pet } // Where adds a new predicate for the builder. @@ -35,16 +34,13 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // SetName sets the name field. func (pu *PetUpdate) SetName(s string) *PetUpdate { - pu.name = &s + pu.mutation.SetName(s) return pu } // SetOwnerID sets the owner edge to User by id. func (pu *PetUpdate) SetOwnerID(id int) *PetUpdate { - if pu.owner == nil { - pu.owner = make(map[int]struct{}) - } - pu.owner[id] = struct{}{} + pu.mutation.SetOwnerID(id) return pu } @@ -63,16 +59,37 @@ func (pu *PetUpdate) SetOwner(u *User) *PetUpdate { // ClearOwner clears the owner edge to User. func (pu *PetUpdate) ClearOwner() *PetUpdate { - pu.clearedOwner = true + pu.mutation.ClearOwner() return pu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - if len(pu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } } - return pu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -115,14 +132,14 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := pu.name; value != nil { + if value, ok := pu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) } - if pu.clearedOwner { + if pu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -138,7 +155,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.owner; len(nodes) > 0 { + if nodes := pu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -152,7 +169,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -171,24 +188,19 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id int - name *string - owner map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *PetMutation } // SetName sets the name field. func (puo *PetUpdateOne) SetName(s string) *PetUpdateOne { - puo.name = &s + puo.mutation.SetName(s) return puo } // SetOwnerID sets the owner edge to User by id. func (puo *PetUpdateOne) SetOwnerID(id int) *PetUpdateOne { - if puo.owner == nil { - puo.owner = make(map[int]struct{}) - } - puo.owner[id] = struct{}{} + puo.mutation.SetOwnerID(id) return puo } @@ -207,16 +219,37 @@ func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne { // ClearOwner clears the owner edge to User. func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne { - puo.clearedOwner = true + puo.mutation.ClearOwner() return puo } // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - if len(puo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } } - return puo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -247,20 +280,24 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { Table: pet.Table, Columns: pet.Columns, ID: &sqlgraph.FieldSpec{ - Value: puo.id, Type: field.TypeInt, Column: pet.FieldID, }, }, } - if value := puo.name; value != nil { + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := puo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) } - if puo.clearedOwner { + if puo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -276,7 +313,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.owner; len(nodes) > 0 { + if nodes := puo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -290,7 +327,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2m2types/ent/privacy/privacy.go b/examples/o2m2types/ent/privacy/privacy.go new file mode 100644 index 000000000..0b4dd1a6d --- /dev/null +++ b/examples/o2m2types/ent/privacy/privacy.go @@ -0,0 +1,195 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/o2m2types/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/o2m2types/ent/runtime.go b/examples/o2m2types/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/o2m2types/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/o2m2types/ent/runtime/runtime.go b/examples/o2m2types/ent/runtime/runtime.go new file mode 100644 index 000000000..a786438ea --- /dev/null +++ b/examples/o2m2types/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/o2m2types/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/o2m2types/ent/tx.go b/examples/o2m2types/ent/tx.go index 266a7aace..7a11242bc 100644 --- a/examples/o2m2types/ent/tx.go +++ b/examples/o2m2types/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/o2m2types/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -34,12 +33,14 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Pet: NewPetClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Pet = NewPetClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/o2m2types/ent/user/user.go b/examples/o2m2types/ent/user/user.go index 6ecacea60..c522b679e 100644 --- a/examples/o2m2types/ent/user/user.go +++ b/examples/o2m2types/ent/user/user.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" + // Table holds the table name of the user in the database. Table = "users" // PetsTable is the table the holds the pets relation/edge. diff --git a/examples/o2m2types/ent/user_create.go b/examples/o2m2types/ent/user_create.go index 250b26096..895db8409 100644 --- a/examples/o2m2types/ent/user_create.go +++ b/examples/o2m2types/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/o2m2types/ent/pet" @@ -19,31 +20,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - pets map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // AddPetIDs adds the pets edge to Pet by ids. func (uc *UserCreate) AddPetIDs(ids ...int) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[int]struct{}) - } - for i := range ids { - uc.pets[ids[i]] = struct{}{} - } + uc.mutation.AddPetIDs(ids...) return uc } @@ -58,13 +53,36 @@ func (uc *UserCreate) AddPets(p ...*Pet) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -87,23 +105,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.pets; len(nodes) > 0 { + if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -117,7 +135,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2m2types/ent/user_delete.go b/examples/o2m2types/ent/user_delete.go index b30bebb63..57c071124 100644 --- a/examples/o2m2types/ent/user_delete.go +++ b/examples/o2m2types/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2m2types/ent/user_update.go b/examples/o2m2types/ent/user_update.go index c4256d7fd..3190982a7 100644 --- a/examples/o2m2types/ent/user_update.go +++ b/examples/o2m2types/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,12 +21,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - pets map[int]struct{} - removedPets map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -36,35 +34,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // AddPetIDs adds the pets edge to Pet by ids. func (uu *UserUpdate) AddPetIDs(ids ...int) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[int]struct{}) - } - for i := range ids { - uu.pets[ids[i]] = struct{}{} - } + uu.mutation.AddPetIDs(ids...) return uu } @@ -79,12 +68,7 @@ func (uu *UserUpdate) AddPets(p ...*Pet) *UserUpdate { // RemovePetIDs removes the pets edge to Pet by ids. func (uu *UserUpdate) RemovePetIDs(ids ...int) *UserUpdate { - if uu.removedPets == nil { - uu.removedPets = make(map[int]struct{}) - } - for i := range ids { - uu.removedPets[ids[i]] = struct{}{} - } + uu.mutation.RemovePetIDs(ids...) return uu } @@ -99,7 +83,31 @@ func (uu *UserUpdate) RemovePets(p ...*Pet) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -142,28 +150,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedPets; len(nodes) > 0 { + if nodes := uu.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -177,12 +185,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.pets; len(nodes) > 0 { + if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -196,7 +204,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -215,45 +223,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - pets map[int]struct{} - removedPets map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // AddPetIDs adds the pets edge to Pet by ids. func (uuo *UserUpdateOne) AddPetIDs(ids ...int) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[int]struct{}) - } - for i := range ids { - uuo.pets[ids[i]] = struct{}{} - } + uuo.mutation.AddPetIDs(ids...) return uuo } @@ -268,12 +263,7 @@ func (uuo *UserUpdateOne) AddPets(p ...*Pet) *UserUpdateOne { // RemovePetIDs removes the pets edge to Pet by ids. func (uuo *UserUpdateOne) RemovePetIDs(ids ...int) *UserUpdateOne { - if uuo.removedPets == nil { - uuo.removedPets = make(map[int]struct{}) - } - for i := range ids { - uuo.removedPets[ids[i]] = struct{}{} - } + uuo.mutation.RemovePetIDs(ids...) return uuo } @@ -288,7 +278,31 @@ func (uuo *UserUpdateOne) RemovePets(p ...*Pet) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -319,34 +333,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedPets; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -360,12 +378,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.pets; len(nodes) > 0 { + if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -379,7 +397,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2mrecur/ent/client.go b/examples/o2mrecur/ent/client.go index 02c9a6f7e..de7b375b0 100644 --- a/examples/o2mrecur/ent/client.go +++ b/examples/o2mrecur/ent/client.go @@ -31,13 +31,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Node: NewNodeClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Node = NewNodeClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -65,7 +68,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Node: NewNodeClient(cfg), @@ -83,12 +86,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Node: NewNodeClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -96,6 +97,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Node.Use(hooks...) +} + // NodeClient is a client for the Node schema. type NodeClient struct { config @@ -106,14 +113,22 @@ func NewNodeClient(c config) *NodeClient { return &NodeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `node.Hooks(f(g(h())))`. +func (c *NodeClient) Use(hooks ...Hook) { + c.hooks.Node = append(c.hooks.Node, hooks...) +} + // Create returns a create builder for Node. func (c *NodeClient) Create() *NodeCreate { - return &NodeCreate{config: c.config} + mutation := newNodeMutation(c.config, OpCreate) + return &NodeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Node. func (c *NodeClient) Update() *NodeUpdate { - return &NodeUpdate{config: c.config} + mutation := newNodeMutation(c.config, OpUpdate) + return &NodeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -123,12 +138,15 @@ func (c *NodeClient) UpdateOne(n *Node) *NodeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *NodeClient) UpdateOneID(id int) *NodeUpdateOne { - return &NodeUpdateOne{config: c.config, id: id} + mutation := newNodeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &NodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Node. func (c *NodeClient) Delete() *NodeDelete { - return &NodeDelete{config: c.config} + mutation := newNodeMutation(c.config, OpDelete) + return &NodeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -138,7 +156,10 @@ func (c *NodeClient) DeleteOne(n *Node) *NodeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *NodeClient) DeleteOneID(id int) *NodeDeleteOne { - return &NodeDeleteOne{c.Delete().Where(node.ID(id))} + builder := c.Delete().Where(node.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &NodeDeleteOne{builder} } // Create returns a query builder for Node. @@ -187,3 +208,8 @@ func (c *NodeClient) QueryChildren(n *Node) *NodeQuery { return query } + +// Hooks returns the client hooks. +func (c *NodeClient) Hooks() []Hook { + return c.hooks.Node +} diff --git a/examples/o2mrecur/ent/config.go b/examples/o2mrecur/ent/config.go index dd64c4cf6..f38504630 100644 --- a/examples/o2mrecur/ent/config.go +++ b/examples/o2mrecur/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Node []ent.Hook } // Options applies the options on the config object. diff --git a/examples/o2mrecur/ent/ent.go b/examples/o2mrecur/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/o2mrecur/ent/ent.go +++ b/examples/o2mrecur/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/o2mrecur/ent/hook/hook.go b/examples/o2mrecur/ent/hook/hook.go new file mode 100644 index 000000000..905e8611f --- /dev/null +++ b/examples/o2mrecur/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/o2mrecur/ent" +) + +// The NodeFunc type is an adapter to allow the use of ordinary +// function as Node mutator. +type NodeFunc func(context.Context, *ent.NodeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f NodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.NodeMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/o2mrecur/ent/mutation.go b/examples/o2mrecur/ent/mutation.go new file mode 100644 index 000000000..9bbc89cc0 --- /dev/null +++ b/examples/o2mrecur/ent/mutation.go @@ -0,0 +1,418 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/o2mrecur/ent/node" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeNode = "Node" +) + +// NodeMutation represents an operation that mutate the Nodes +// nodes in the graph. +type NodeMutation struct { + config + op Op + typ string + id *int + value *int + addvalue *int + clearedFields map[string]bool + parent *int + clearedparent bool + children map[int]struct{} + removedchildren map[int]struct{} +} + +var _ ent.Mutation = (*NodeMutation)(nil) + +// newNodeMutation creates new mutation for $n.Name. +func newNodeMutation(c config, op Op) *NodeMutation { + return &NodeMutation{ + config: c, + op: op, + typ: TypeNode, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m NodeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m NodeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *NodeMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetValue sets the value field. +func (m *NodeMutation) SetValue(i int) { + m.value = &i + m.addvalue = nil +} + +// Value returns the value value in the mutation. +func (m *NodeMutation) Value() (r int, exists bool) { + v := m.value + if v == nil { + return + } + return *v, true +} + +// AddValue adds i to value. +func (m *NodeMutation) AddValue(i int) { + if m.addvalue != nil { + *m.addvalue += i + } else { + m.addvalue = &i + } +} + +// AddedValue returns the value that was added to the value field in this mutation. +func (m *NodeMutation) AddedValue() (r int, exists bool) { + v := m.addvalue + if v == nil { + return + } + return *v, true +} + +// ResetValue reset all changes of the value field. +func (m *NodeMutation) ResetValue() { + m.value = nil + m.addvalue = nil +} + +// SetParentID sets the parent edge to Node by id. +func (m *NodeMutation) SetParentID(id int) { + m.parent = &id +} + +// ClearParent clears the parent edge to Node. +func (m *NodeMutation) ClearParent() { + m.clearedparent = true +} + +// ParentCleared returns if the edge parent was cleared. +func (m *NodeMutation) ParentCleared() bool { + return m.clearedparent +} + +// ParentID returns the parent id in the mutation. +func (m *NodeMutation) ParentID() (id int, exists bool) { + if m.parent != nil { + return *m.parent, true + } + return +} + +// ParentIDs returns the parent ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// ParentID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) ParentIDs() (ids []int) { + if id := m.parent; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetParent reset all changes of the parent edge. +func (m *NodeMutation) ResetParent() { + m.parent = nil + m.clearedparent = false +} + +// AddChildIDs adds the children edge to Node by ids. +func (m *NodeMutation) AddChildIDs(ids ...int) { + if m.children == nil { + m.children = make(map[int]struct{}) + } + for i := range ids { + m.children[ids[i]] = struct{}{} + } +} + +// RemoveChildIDs removes the children edge to Node by ids. +func (m *NodeMutation) RemoveChildIDs(ids ...int) { + if m.removedchildren == nil { + m.removedchildren = make(map[int]struct{}) + } + for i := range ids { + m.removedchildren[ids[i]] = struct{}{} + } +} + +// RemovedChildren returns the removed ids of children. +func (m *NodeMutation) RemovedChildrenIDs() (ids []int) { + for id := range m.removedchildren { + ids = append(ids, id) + } + return +} + +// ChildrenIDs returns the children ids in the mutation. +func (m *NodeMutation) ChildrenIDs() (ids []int) { + for id := range m.children { + ids = append(ids, id) + } + return +} + +// ResetChildren reset all changes of the children edge. +func (m *NodeMutation) ResetChildren() { + m.children = nil + m.removedchildren = nil +} + +// Op returns the operation name. +func (m *NodeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Node). +func (m *NodeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *NodeMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.value != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *NodeMutation) Field(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.Value() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) SetField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValue(v) + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *NodeMutation) AddedFields() []string { + var fields []string + if m.addvalue != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *NodeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.AddedValue() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) AddField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValue(v) + return nil + } + return fmt.Errorf("unknown Node numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *NodeMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *NodeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *NodeMutation) ClearField(name string) error { + return fmt.Errorf("unknown Node nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *NodeMutation) ResetField(name string) error { + switch name { + case node.FieldValue: + m.ResetValue() + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *NodeMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.parent != nil { + edges = append(edges, node.EdgeParent) + } + if m.children != nil { + edges = append(edges, node.EdgeChildren) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *NodeMutation) AddedIDs(name string) []ent.Value { + switch name { + case node.EdgeParent: + if id := m.parent; id != nil { + return []ent.Value{*id} + } + case node.EdgeChildren: + ids := make([]ent.Value, 0, len(m.children)) + for id := range m.children { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *NodeMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedchildren != nil { + edges = append(edges, node.EdgeChildren) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *NodeMutation) RemovedIDs(name string) []ent.Value { + switch name { + case node.EdgeChildren: + ids := make([]ent.Value, 0, len(m.removedchildren)) + for id := range m.removedchildren { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *NodeMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedparent { + edges = append(edges, node.EdgeParent) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *NodeMutation) EdgeCleared(name string) bool { + switch name { + case node.EdgeParent: + return m.clearedparent + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *NodeMutation) ClearEdge(name string) error { + switch name { + case node.EdgeParent: + m.ClearParent() + return nil + } + return fmt.Errorf("unknown Node unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *NodeMutation) ResetEdge(name string) error { + switch name { + case node.EdgeParent: + m.ResetParent() + return nil + case node.EdgeChildren: + m.ResetChildren() + return nil + } + return fmt.Errorf("unknown Node edge %s", name) +} diff --git a/examples/o2mrecur/ent/node/node.go b/examples/o2mrecur/ent/node/node.go index 08a1dcda2..877936835 100644 --- a/examples/o2mrecur/ent/node/node.go +++ b/examples/o2mrecur/ent/node/node.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the node type in the database. Label = "node" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldValue holds the string denoting the value vertex property in the database. + FieldID = "id" // FieldValue holds the string denoting the value vertex property in the database. FieldValue = "value" + // EdgeParent holds the string denoting the parent edge name in mutations. + EdgeParent = "parent" + // EdgeChildren holds the string denoting the children edge name in mutations. + EdgeChildren = "children" + // Table holds the table name of the node in the database. Table = "nodes" // ParentTable is the table the holds the parent relation/edge. diff --git a/examples/o2mrecur/ent/node_create.go b/examples/o2mrecur/ent/node_create.go index 71a0d58d5..d464c04e3 100644 --- a/examples/o2mrecur/ent/node_create.go +++ b/examples/o2mrecur/ent/node_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/o2mrecur/ent/node" @@ -18,23 +19,19 @@ import ( // NodeCreate is the builder for creating a Node entity. type NodeCreate struct { config - value *int - parent map[int]struct{} - children map[int]struct{} + mutation *NodeMutation + hooks []Hook } // SetValue sets the value field. func (nc *NodeCreate) SetValue(i int) *NodeCreate { - nc.value = &i + nc.mutation.SetValue(i) return nc } // SetParentID sets the parent edge to Node by id. func (nc *NodeCreate) SetParentID(id int) *NodeCreate { - if nc.parent == nil { - nc.parent = make(map[int]struct{}) - } - nc.parent[id] = struct{}{} + nc.mutation.SetParentID(id) return nc } @@ -53,12 +50,7 @@ func (nc *NodeCreate) SetParent(n *Node) *NodeCreate { // AddChildIDs adds the children edge to Node by ids. func (nc *NodeCreate) AddChildIDs(ids ...int) *NodeCreate { - if nc.children == nil { - nc.children = make(map[int]struct{}) - } - for i := range ids { - nc.children[ids[i]] = struct{}{} - } + nc.mutation.AddChildIDs(ids...) return nc } @@ -73,13 +65,33 @@ func (nc *NodeCreate) AddChildren(n ...*Node) *NodeCreate { // Save creates the Node in the database. func (nc *NodeCreate) Save(ctx context.Context) (*Node, error) { - if nc.value == nil { + if _, ok := nc.mutation.Value(); !ok { return nil, errors.New("ent: missing required field \"value\"") } - if len(nc.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") + var ( + err error + node *Node + ) + if len(nc.hooks) == 0 { + node, err = nc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nc.mutation = mutation + node, err = nc.sqlSave(ctx) + return node, err + }) + for i := len(nc.hooks); i > 0; i-- { + mut = nc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nc.mutation); err != nil { + return nil, err + } } - return nc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -102,15 +114,15 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, } ) - if value := nc.value; value != nil { + if value, ok := nc.mutation.Value(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) - n.Value = *value + n.Value = value } - if nodes := nc.parent; len(nodes) > 0 { + if nodes := nc.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -124,12 +136,12 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := nc.children; len(nodes) > 0 { + if nodes := nc.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -143,7 +155,7 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2mrecur/ent/node_delete.go b/examples/o2mrecur/ent/node_delete.go index c9a76ca16..252d161b5 100644 --- a/examples/o2mrecur/ent/node_delete.go +++ b/examples/o2mrecur/ent/node_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // NodeDelete is the builder for deleting a Node entity. type NodeDelete struct { config + hooks []Hook + mutation *NodeMutation predicates []predicate.Node } @@ -30,7 +33,30 @@ func (nd *NodeDelete) Where(ps ...predicate.Node) *NodeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (nd *NodeDelete) Exec(ctx context.Context) (int, error) { - return nd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(nd.hooks) == 0 { + affected, err = nd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nd.mutation = mutation + affected, err = nd.sqlExec(ctx) + return affected, err + }) + for i := len(nd.hooks); i > 0; i-- { + mut = nd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2mrecur/ent/node_update.go b/examples/o2mrecur/ent/node_update.go index a3c10a276..d4f5abcd2 100644 --- a/examples/o2mrecur/ent/node_update.go +++ b/examples/o2mrecur/ent/node_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,13 +20,9 @@ import ( // NodeUpdate is the builder for updating Node entities. type NodeUpdate struct { config - value *int - addvalue *int - parent map[int]struct{} - children map[int]struct{} - clearedParent bool - removedChildren map[int]struct{} - predicates []predicate.Node + hooks []Hook + mutation *NodeMutation + predicates []predicate.Node } // Where adds a new predicate for the builder. @@ -37,27 +33,20 @@ func (nu *NodeUpdate) Where(ps ...predicate.Node) *NodeUpdate { // SetValue sets the value field. func (nu *NodeUpdate) SetValue(i int) *NodeUpdate { - nu.value = &i - nu.addvalue = nil + nu.mutation.ResetValue() + nu.mutation.SetValue(i) return nu } // AddValue adds i to value. func (nu *NodeUpdate) AddValue(i int) *NodeUpdate { - if nu.addvalue == nil { - nu.addvalue = &i - } else { - *nu.addvalue += i - } + nu.mutation.AddValue(i) return nu } // SetParentID sets the parent edge to Node by id. func (nu *NodeUpdate) SetParentID(id int) *NodeUpdate { - if nu.parent == nil { - nu.parent = make(map[int]struct{}) - } - nu.parent[id] = struct{}{} + nu.mutation.SetParentID(id) return nu } @@ -76,12 +65,7 @@ func (nu *NodeUpdate) SetParent(n *Node) *NodeUpdate { // AddChildIDs adds the children edge to Node by ids. func (nu *NodeUpdate) AddChildIDs(ids ...int) *NodeUpdate { - if nu.children == nil { - nu.children = make(map[int]struct{}) - } - for i := range ids { - nu.children[ids[i]] = struct{}{} - } + nu.mutation.AddChildIDs(ids...) return nu } @@ -96,18 +80,13 @@ func (nu *NodeUpdate) AddChildren(n ...*Node) *NodeUpdate { // ClearParent clears the parent edge to Node. func (nu *NodeUpdate) ClearParent() *NodeUpdate { - nu.clearedParent = true + nu.mutation.ClearParent() return nu } // RemoveChildIDs removes the children edge to Node by ids. func (nu *NodeUpdate) RemoveChildIDs(ids ...int) *NodeUpdate { - if nu.removedChildren == nil { - nu.removedChildren = make(map[int]struct{}) - } - for i := range ids { - nu.removedChildren[ids[i]] = struct{}{} - } + nu.mutation.RemoveChildIDs(ids...) return nu } @@ -122,10 +101,31 @@ func (nu *NodeUpdate) RemoveChildren(n ...*Node) *NodeUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (nu *NodeUpdate) Save(ctx context.Context) (int, error) { - if len(nu.parent) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"parent\"") + + var ( + err error + affected int + ) + if len(nu.hooks) == 0 { + affected, err = nu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nu.mutation = mutation + affected, err = nu.sqlSave(ctx) + return affected, err + }) + for i := len(nu.hooks); i > 0; i-- { + mut = nu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nu.mutation); err != nil { + return 0, err + } } - return nu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -168,21 +168,21 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := nu.value; value != nil { + if value, ok := nu.mutation.Value(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if value := nu.addvalue; value != nil { + if value, ok := nu.mutation.AddedValue(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if nu.clearedParent { + if nu.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -198,7 +198,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nu.parent; len(nodes) > 0 { + if nodes := nu.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -212,12 +212,12 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := nu.removedChildren; len(nodes) > 0 { + if nodes := nu.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -231,12 +231,12 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nu.children; len(nodes) > 0 { + if nodes := nu.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -250,7 +250,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -269,38 +269,26 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { // NodeUpdateOne is the builder for updating a single Node entity. type NodeUpdateOne struct { config - id int - value *int - addvalue *int - parent map[int]struct{} - children map[int]struct{} - clearedParent bool - removedChildren map[int]struct{} + hooks []Hook + mutation *NodeMutation } // SetValue sets the value field. func (nuo *NodeUpdateOne) SetValue(i int) *NodeUpdateOne { - nuo.value = &i - nuo.addvalue = nil + nuo.mutation.ResetValue() + nuo.mutation.SetValue(i) return nuo } // AddValue adds i to value. func (nuo *NodeUpdateOne) AddValue(i int) *NodeUpdateOne { - if nuo.addvalue == nil { - nuo.addvalue = &i - } else { - *nuo.addvalue += i - } + nuo.mutation.AddValue(i) return nuo } // SetParentID sets the parent edge to Node by id. func (nuo *NodeUpdateOne) SetParentID(id int) *NodeUpdateOne { - if nuo.parent == nil { - nuo.parent = make(map[int]struct{}) - } - nuo.parent[id] = struct{}{} + nuo.mutation.SetParentID(id) return nuo } @@ -319,12 +307,7 @@ func (nuo *NodeUpdateOne) SetParent(n *Node) *NodeUpdateOne { // AddChildIDs adds the children edge to Node by ids. func (nuo *NodeUpdateOne) AddChildIDs(ids ...int) *NodeUpdateOne { - if nuo.children == nil { - nuo.children = make(map[int]struct{}) - } - for i := range ids { - nuo.children[ids[i]] = struct{}{} - } + nuo.mutation.AddChildIDs(ids...) return nuo } @@ -339,18 +322,13 @@ func (nuo *NodeUpdateOne) AddChildren(n ...*Node) *NodeUpdateOne { // ClearParent clears the parent edge to Node. func (nuo *NodeUpdateOne) ClearParent() *NodeUpdateOne { - nuo.clearedParent = true + nuo.mutation.ClearParent() return nuo } // RemoveChildIDs removes the children edge to Node by ids. func (nuo *NodeUpdateOne) RemoveChildIDs(ids ...int) *NodeUpdateOne { - if nuo.removedChildren == nil { - nuo.removedChildren = make(map[int]struct{}) - } - for i := range ids { - nuo.removedChildren[ids[i]] = struct{}{} - } + nuo.mutation.RemoveChildIDs(ids...) return nuo } @@ -365,10 +343,31 @@ func (nuo *NodeUpdateOne) RemoveChildren(n ...*Node) *NodeUpdateOne { // Save executes the query and returns the updated entity. func (nuo *NodeUpdateOne) Save(ctx context.Context) (*Node, error) { - if len(nuo.parent) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"parent\"") + + var ( + err error + node *Node + ) + if len(nuo.hooks) == 0 { + node, err = nuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nuo.mutation = mutation + node, err = nuo.sqlSave(ctx) + return node, err + }) + for i := len(nuo.hooks); i > 0; i-- { + mut = nuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nuo.mutation); err != nil { + return nil, err + } } - return nuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -399,27 +398,31 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { Table: node.Table, Columns: node.Columns, ID: &sqlgraph.FieldSpec{ - Value: nuo.id, Type: field.TypeInt, Column: node.FieldID, }, }, } - if value := nuo.value; value != nil { + id, ok := nuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Node.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := nuo.mutation.Value(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if value := nuo.addvalue; value != nil { + if value, ok := nuo.mutation.AddedValue(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if nuo.clearedParent { + if nuo.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -435,7 +438,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nuo.parent; len(nodes) > 0 { + if nodes := nuo.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -449,12 +452,12 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := nuo.removedChildren; len(nodes) > 0 { + if nodes := nuo.mutation.RemovedChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -468,12 +471,12 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nuo.children; len(nodes) > 0 { + if nodes := nuo.mutation.ChildrenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -487,7 +490,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2mrecur/ent/privacy/privacy.go b/examples/o2mrecur/ent/privacy/privacy.go new file mode 100644 index 000000000..7331ad58a --- /dev/null +++ b/examples/o2mrecur/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/o2mrecur/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The NodeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type NodeReadRuleFunc func(context.Context, *ent.Node) error + +// EvalRead calls f(ctx, v). +func (f NodeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Node); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Node", v) +} + +// The NodeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type NodeWriteRuleFunc func(context.Context, *ent.NodeMutation) error + +// EvalWrite calls f(ctx, m). +func (f NodeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.NodeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.NodeMutation", m) +} diff --git a/examples/o2mrecur/ent/runtime.go b/examples/o2mrecur/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/o2mrecur/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/o2mrecur/ent/runtime/runtime.go b/examples/o2mrecur/ent/runtime/runtime.go new file mode 100644 index 000000000..a39425941 --- /dev/null +++ b/examples/o2mrecur/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/o2mrecur/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/o2mrecur/ent/tx.go b/examples/o2mrecur/ent/tx.go index 3cc407a97..ea811ee19 100644 --- a/examples/o2mrecur/ent/tx.go +++ b/examples/o2mrecur/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/o2mrecur/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Node: NewNodeClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Node = NewNodeClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/o2o2types/ent/card/card.go b/examples/o2o2types/ent/card/card.go index afdaec4a8..d63f0951c 100644 --- a/examples/o2o2types/ent/card/card.go +++ b/examples/o2o2types/ent/card/card.go @@ -10,11 +10,12 @@ const ( // Label holds the string label denoting the card type in the database. Label = "card" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldExpired holds the string denoting the expired vertex property in the database. - FieldExpired = "expired" - // FieldNumber holds the string denoting the number vertex property in the database. - FieldNumber = "number" + FieldID = "id" // FieldExpired holds the string denoting the expired vertex property in the database. + FieldExpired = "expired" // FieldNumber holds the string denoting the number vertex property in the database. + FieldNumber = "number" + + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" // Table holds the table name of the card in the database. Table = "cards" diff --git a/examples/o2o2types/ent/card_create.go b/examples/o2o2types/ent/card_create.go index bf9d498b9..54264a746 100644 --- a/examples/o2o2types/ent/card_create.go +++ b/examples/o2o2types/ent/card_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "time" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,29 +21,25 @@ import ( // CardCreate is the builder for creating a Card entity. type CardCreate struct { config - expired *time.Time - number *string - owner map[int]struct{} + mutation *CardMutation + hooks []Hook } // SetExpired sets the expired field. func (cc *CardCreate) SetExpired(t time.Time) *CardCreate { - cc.expired = &t + cc.mutation.SetExpired(t) return cc } // SetNumber sets the number field. func (cc *CardCreate) SetNumber(s string) *CardCreate { - cc.number = &s + cc.mutation.SetNumber(s) return cc } // SetOwnerID sets the owner edge to User by id. func (cc *CardCreate) SetOwnerID(id int) *CardCreate { - if cc.owner == nil { - cc.owner = make(map[int]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -53,19 +50,39 @@ func (cc *CardCreate) SetOwner(u *User) *CardCreate { // Save creates the Card in the database. func (cc *CardCreate) Save(ctx context.Context) (*Card, error) { - if cc.expired == nil { + if _, ok := cc.mutation.Expired(); !ok { return nil, errors.New("ent: missing required field \"expired\"") } - if cc.number == nil { + if _, ok := cc.mutation.Number(); !ok { return nil, errors.New("ent: missing required field \"number\"") } - if len(cc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - if cc.owner == nil { + if _, ok := cc.mutation.OwnerID(); !ok { return nil, errors.New("ent: missing required edge \"owner\"") } - return cc.sqlSave(ctx) + var ( + err error + node *Card + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -88,23 +105,23 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { }, } ) - if value := cc.expired; value != nil { + if value, ok := cc.mutation.Expired(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldExpired, }) - c.Expired = *value + c.Expired = value } - if value := cc.number; value != nil { + if value, ok := cc.mutation.Number(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldNumber, }) - c.Number = *value + c.Number = value } - if nodes := cc.owner; len(nodes) > 0 { + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -118,7 +135,7 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2o2types/ent/card_delete.go b/examples/o2o2types/ent/card_delete.go index dad1d5eef..e8daece1c 100644 --- a/examples/o2o2types/ent/card_delete.go +++ b/examples/o2o2types/ent/card_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CardDelete is the builder for deleting a Card entity. type CardDelete struct { config + hooks []Hook + mutation *CardMutation predicates []predicate.Card } @@ -30,7 +33,30 @@ func (cd *CardDelete) Where(ps ...predicate.Card) *CardDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CardDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2o2types/ent/card_update.go b/examples/o2o2types/ent/card_update.go index c182371ab..e10b05e4b 100644 --- a/examples/o2o2types/ent/card_update.go +++ b/examples/o2o2types/ent/card_update.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "time" "github.com/facebookincubator/ent/dialect/sql" @@ -22,11 +23,9 @@ import ( // CardUpdate is the builder for updating Card entities. type CardUpdate struct { config - expired *time.Time - number *string - owner map[int]struct{} - clearedOwner bool - predicates []predicate.Card + hooks []Hook + mutation *CardMutation + predicates []predicate.Card } // Where adds a new predicate for the builder. @@ -37,22 +36,19 @@ func (cu *CardUpdate) Where(ps ...predicate.Card) *CardUpdate { // SetExpired sets the expired field. func (cu *CardUpdate) SetExpired(t time.Time) *CardUpdate { - cu.expired = &t + cu.mutation.SetExpired(t) return cu } // SetNumber sets the number field. func (cu *CardUpdate) SetNumber(s string) *CardUpdate { - cu.number = &s + cu.mutation.SetNumber(s) return cu } // SetOwnerID sets the owner edge to User by id. func (cu *CardUpdate) SetOwnerID(id int) *CardUpdate { - if cu.owner == nil { - cu.owner = make(map[int]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -63,19 +59,40 @@ func (cu *CardUpdate) SetOwner(u *User) *CardUpdate { // ClearOwner clears the owner edge to User. func (cu *CardUpdate) ClearOwner() *CardUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CardUpdate) Save(ctx context.Context) (int, error) { - if len(cu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - if cu.clearedOwner && cu.owner == nil { + + if _, ok := cu.mutation.OwnerID(); cu.mutation.OwnerCleared() && !ok { return 0, errors.New("ent: clearing a unique edge \"owner\"") } - return cu.sqlSave(ctx) + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -118,21 +135,21 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := cu.expired; value != nil { + if value, ok := cu.mutation.Expired(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldExpired, }) } - if value := cu.number; value != nil { + if value, ok := cu.mutation.Number(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldNumber, }) } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -148,7 +165,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.owner; len(nodes) > 0 { + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -162,7 +179,7 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -181,31 +198,25 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) { // CardUpdateOne is the builder for updating a single Card entity. type CardUpdateOne struct { config - id int - expired *time.Time - number *string - owner map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *CardMutation } // SetExpired sets the expired field. func (cuo *CardUpdateOne) SetExpired(t time.Time) *CardUpdateOne { - cuo.expired = &t + cuo.mutation.SetExpired(t) return cuo } // SetNumber sets the number field. func (cuo *CardUpdateOne) SetNumber(s string) *CardUpdateOne { - cuo.number = &s + cuo.mutation.SetNumber(s) return cuo } // SetOwnerID sets the owner edge to User by id. func (cuo *CardUpdateOne) SetOwnerID(id int) *CardUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[int]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -216,19 +227,40 @@ func (cuo *CardUpdateOne) SetOwner(u *User) *CardUpdateOne { // ClearOwner clears the owner edge to User. func (cuo *CardUpdateOne) ClearOwner() *CardUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // Save executes the query and returns the updated entity. func (cuo *CardUpdateOne) Save(ctx context.Context) (*Card, error) { - if len(cuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") - } - if cuo.clearedOwner && cuo.owner == nil { + + if _, ok := cuo.mutation.OwnerID(); cuo.mutation.OwnerCleared() && !ok { return nil, errors.New("ent: clearing a unique edge \"owner\"") } - return cuo.sqlSave(ctx) + var ( + err error + node *Card + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -259,27 +291,31 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { Table: card.Table, Columns: card.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeInt, Column: card.FieldID, }, }, } - if value := cuo.expired; value != nil { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Card.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.Expired(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: card.FieldExpired, }) } - if value := cuo.number; value != nil { + if value, ok := cuo.mutation.Number(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: card.FieldNumber, }) } - if cuo.clearedOwner { + if cuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -295,7 +331,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.owner; len(nodes) > 0 { + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -309,7 +345,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2o2types/ent/client.go b/examples/o2o2types/ent/client.go index e958aa02a..5b6402ae6 100644 --- a/examples/o2o2types/ent/client.go +++ b/examples/o2o2types/ent/client.go @@ -34,14 +34,17 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Card: NewCardClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Card = NewCardClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -69,7 +72,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Card: NewCardClient(cfg), @@ -88,13 +91,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Card: NewCardClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -102,6 +102,13 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Card.Use(hooks...) + c.User.Use(hooks...) +} + // CardClient is a client for the Card schema. type CardClient struct { config @@ -112,14 +119,22 @@ func NewCardClient(c config) *CardClient { return &CardClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `card.Hooks(f(g(h())))`. +func (c *CardClient) Use(hooks ...Hook) { + c.hooks.Card = append(c.hooks.Card, hooks...) +} + // Create returns a create builder for Card. func (c *CardClient) Create() *CardCreate { - return &CardCreate{config: c.config} + mutation := newCardMutation(c.config, OpCreate) + return &CardCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Card. func (c *CardClient) Update() *CardUpdate { - return &CardUpdate{config: c.config} + mutation := newCardMutation(c.config, OpUpdate) + return &CardUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -129,12 +144,15 @@ func (c *CardClient) UpdateOne(ca *Card) *CardUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CardClient) UpdateOneID(id int) *CardUpdateOne { - return &CardUpdateOne{config: c.config, id: id} + mutation := newCardMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CardUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Card. func (c *CardClient) Delete() *CardDelete { - return &CardDelete{config: c.config} + mutation := newCardMutation(c.config, OpDelete) + return &CardDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -144,7 +162,10 @@ func (c *CardClient) DeleteOne(ca *Card) *CardDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CardClient) DeleteOneID(id int) *CardDeleteOne { - return &CardDeleteOne{c.Delete().Where(card.ID(id))} + builder := c.Delete().Where(card.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CardDeleteOne{builder} } // Create returns a query builder for Card. @@ -180,6 +201,11 @@ func (c *CardClient) QueryOwner(ca *Card) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *CardClient) Hooks() []Hook { + return c.hooks.Card +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -190,14 +216,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -207,12 +241,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -222,7 +259,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -257,3 +297,8 @@ func (c *UserClient) QueryCard(u *User) *CardQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/o2o2types/ent/config.go b/examples/o2o2types/ent/config.go index dd64c4cf6..9ca84f60e 100644 --- a/examples/o2o2types/ent/config.go +++ b/examples/o2o2types/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,14 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Card []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/o2o2types/ent/ent.go b/examples/o2o2types/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/o2o2types/ent/ent.go +++ b/examples/o2o2types/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/o2o2types/ent/hook/hook.go b/examples/o2o2types/ent/hook/hook.go new file mode 100644 index 000000000..fece1274b --- /dev/null +++ b/examples/o2o2types/ent/hook/hook.go @@ -0,0 +1,74 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/o2o2types/ent" +) + +// The CardFunc type is an adapter to allow the use of ordinary +// function as Card mutator. +type CardFunc func(context.Context, *ent.CardMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CardFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CardMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CardMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/o2o2types/ent/mutation.go b/examples/o2o2types/ent/mutation.go new file mode 100644 index 000000000..8cbfdc846 --- /dev/null +++ b/examples/o2o2types/ent/mutation.go @@ -0,0 +1,717 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "time" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/o2o2types/ent/card" + "github.com/facebookincubator/ent/examples/o2o2types/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCard = "Card" + TypeUser = "User" +) + +// CardMutation represents an operation that mutate the Cards +// nodes in the graph. +type CardMutation struct { + config + op Op + typ string + id *int + expired *time.Time + number *string + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*CardMutation)(nil) + +// newCardMutation creates new mutation for $n.Name. +func newCardMutation(c config, op Op) *CardMutation { + return &CardMutation{ + config: c, + op: op, + typ: TypeCard, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CardMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CardMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CardMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetExpired sets the expired field. +func (m *CardMutation) SetExpired(t time.Time) { + m.expired = &t +} + +// Expired returns the expired value in the mutation. +func (m *CardMutation) Expired() (r time.Time, exists bool) { + v := m.expired + if v == nil { + return + } + return *v, true +} + +// ResetExpired reset all changes of the expired field. +func (m *CardMutation) ResetExpired() { + m.expired = nil +} + +// SetNumber sets the number field. +func (m *CardMutation) SetNumber(s string) { + m.number = &s +} + +// Number returns the number value in the mutation. +func (m *CardMutation) Number() (r string, exists bool) { + v := m.number + if v == nil { + return + } + return *v, true +} + +// ResetNumber reset all changes of the number field. +func (m *CardMutation) ResetNumber() { + m.number = nil +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CardMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CardMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CardMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CardMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CardMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CardMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *CardMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Card). +func (m *CardMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CardMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.expired != nil { + fields = append(fields, card.FieldExpired) + } + if m.number != nil { + fields = append(fields, card.FieldNumber) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CardMutation) Field(name string) (ent.Value, bool) { + switch name { + case card.FieldExpired: + return m.Expired() + case card.FieldNumber: + return m.Number() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) SetField(name string, value ent.Value) error { + switch name { + case card.FieldExpired: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExpired(v) + return nil + case card.FieldNumber: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNumber(v) + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CardMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CardMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CardMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Card numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CardMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CardMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CardMutation) ClearField(name string) error { + return fmt.Errorf("unknown Card nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CardMutation) ResetField(name string) error { + switch name { + case card.FieldExpired: + m.ResetExpired() + return nil + case card.FieldNumber: + m.ResetNumber() + return nil + } + return fmt.Errorf("unknown Card field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CardMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, card.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CardMutation) AddedIDs(name string) []ent.Value { + switch name { + case card.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CardMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CardMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CardMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, card.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CardMutation) EdgeCleared(name string) bool { + switch name { + case card.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CardMutation) ClearEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Card unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CardMutation) ResetEdge(name string) error { + switch name { + case card.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Card edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + card *int + clearedcard bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetCardID sets the card edge to Card by id. +func (m *UserMutation) SetCardID(id int) { + m.card = &id +} + +// ClearCard clears the card edge to Card. +func (m *UserMutation) ClearCard() { + m.clearedcard = true +} + +// CardCleared returns if the edge card was cleared. +func (m *UserMutation) CardCleared() bool { + return m.clearedcard +} + +// CardID returns the card id in the mutation. +func (m *UserMutation) CardID() (id int, exists bool) { + if m.card != nil { + return *m.card, true + } + return +} + +// CardIDs returns the card ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// CardID instead. It exists only for internal usage by the builders. +func (m *UserMutation) CardIDs() (ids []int) { + if id := m.card; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetCard reset all changes of the card edge. +func (m *UserMutation) ResetCard() { + m.card = nil + m.clearedcard = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.card != nil { + edges = append(edges, user.EdgeCard) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeCard: + if id := m.card; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedcard { + edges = append(edges, user.EdgeCard) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeCard: + return m.clearedcard + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeCard: + m.ClearCard() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeCard: + m.ResetCard() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/o2o2types/ent/privacy/privacy.go b/examples/o2o2types/ent/privacy/privacy.go new file mode 100644 index 000000000..ea1a0e8a9 --- /dev/null +++ b/examples/o2o2types/ent/privacy/privacy.go @@ -0,0 +1,195 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/o2o2types/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CardReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CardReadRuleFunc func(context.Context, *ent.Card) error + +// EvalRead calls f(ctx, v). +func (f CardReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Card); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Card", v) +} + +// The CardWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CardWriteRuleFunc func(context.Context, *ent.CardMutation) error + +// EvalWrite calls f(ctx, m). +func (f CardWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CardMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CardMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/o2o2types/ent/runtime.go b/examples/o2o2types/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/o2o2types/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/o2o2types/ent/runtime/runtime.go b/examples/o2o2types/ent/runtime/runtime.go new file mode 100644 index 000000000..0333e91e6 --- /dev/null +++ b/examples/o2o2types/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/o2o2types/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/o2o2types/ent/tx.go b/examples/o2o2types/ent/tx.go index 21b2781f6..f671a76d1 100644 --- a/examples/o2o2types/ent/tx.go +++ b/examples/o2o2types/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/o2o2types/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -34,12 +33,14 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Card: NewCardClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Card = NewCardClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/o2o2types/ent/user/user.go b/examples/o2o2types/ent/user/user.go index 046f000c3..0b4a78b92 100644 --- a/examples/o2o2types/ent/user/user.go +++ b/examples/o2o2types/ent/user/user.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeCard holds the string denoting the card edge name in mutations. + EdgeCard = "card" + // Table holds the table name of the user in the database. Table = "users" // CardTable is the table the holds the card relation/edge. diff --git a/examples/o2o2types/ent/user_create.go b/examples/o2o2types/ent/user_create.go index c25a5f0f6..f98185fc4 100644 --- a/examples/o2o2types/ent/user_create.go +++ b/examples/o2o2types/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/o2o2types/ent/card" @@ -19,29 +20,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - card map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetCardID sets the card edge to Card by id. func (uc *UserCreate) SetCardID(id int) *UserCreate { - if uc.card == nil { - uc.card = make(map[int]struct{}) - } - uc.card[id] = struct{}{} + uc.mutation.SetCardID(id) return uc } @@ -60,16 +57,36 @@ func (uc *UserCreate) SetCard(c *Card) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(uc.card) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"card\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -92,23 +109,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.card; len(nodes) > 0 { + if nodes := uc.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -122,7 +139,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2o2types/ent/user_delete.go b/examples/o2o2types/ent/user_delete.go index 3e7d0bfaa..55c65a23c 100644 --- a/examples/o2o2types/ent/user_delete.go +++ b/examples/o2o2types/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2o2types/ent/user_update.go b/examples/o2o2types/ent/user_update.go index c728cbaa1..2ca296abd 100644 --- a/examples/o2o2types/ent/user_update.go +++ b/examples/o2o2types/ent/user_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,12 +21,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - card map[int]struct{} - clearedCard bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -37,33 +34,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetCardID sets the card edge to Card by id. func (uu *UserUpdate) SetCardID(id int) *UserUpdate { - if uu.card == nil { - uu.card = make(map[int]struct{}) - } - uu.card[id] = struct{}{} + uu.mutation.SetCardID(id) return uu } @@ -82,16 +72,37 @@ func (uu *UserUpdate) SetCard(c *Card) *UserUpdate { // ClearCard clears the card edge to Card. func (uu *UserUpdate) ClearCard() *UserUpdate { - uu.clearedCard = true + uu.mutation.ClearCard() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if len(uu.card) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"card\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -134,28 +145,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if uu.clearedCard { + if uu.mutation.CardCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -171,7 +182,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.card; len(nodes) > 0 { + if nodes := uu.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -185,7 +196,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -204,43 +215,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - card map[int]struct{} - clearedCard bool + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetCardID sets the card edge to Card by id. func (uuo *UserUpdateOne) SetCardID(id int) *UserUpdateOne { - if uuo.card == nil { - uuo.card = make(map[int]struct{}) - } - uuo.card[id] = struct{}{} + uuo.mutation.SetCardID(id) return uuo } @@ -259,16 +259,37 @@ func (uuo *UserUpdateOne) SetCard(c *Card) *UserUpdateOne { // ClearCard clears the card edge to Card. func (uuo *UserUpdateOne) ClearCard() *UserUpdateOne { - uuo.clearedCard = true + uuo.mutation.ClearCard() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if len(uuo.card) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"card\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -299,34 +320,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if uuo.clearedCard { + if uuo.mutation.CardCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -342,7 +367,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.card; len(nodes) > 0 { + if nodes := uuo.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -356,7 +381,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2obidi/ent/client.go b/examples/o2obidi/ent/client.go index 07a834183..b5c149eb6 100644 --- a/examples/o2obidi/ent/client.go +++ b/examples/o2obidi/ent/client.go @@ -31,13 +31,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -65,7 +68,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, User: NewUserClient(cfg), @@ -83,12 +86,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -96,6 +97,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.User.Use(hooks...) +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -106,14 +113,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -123,12 +138,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -138,7 +156,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -173,3 +194,8 @@ func (c *UserClient) QuerySpouse(u *User) *UserQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/o2obidi/ent/config.go b/examples/o2obidi/ent/config.go index dd64c4cf6..379610598 100644 --- a/examples/o2obidi/ent/config.go +++ b/examples/o2obidi/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/o2obidi/ent/ent.go b/examples/o2obidi/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/o2obidi/ent/ent.go +++ b/examples/o2obidi/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/o2obidi/ent/hook/hook.go b/examples/o2obidi/ent/hook/hook.go new file mode 100644 index 000000000..a78411b87 --- /dev/null +++ b/examples/o2obidi/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/o2obidi/ent" +) + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/o2obidi/ent/mutation.go b/examples/o2obidi/ent/mutation.go new file mode 100644 index 000000000..8924e5655 --- /dev/null +++ b/examples/o2obidi/ent/mutation.go @@ -0,0 +1,388 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/o2obidi/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeUser = "User" +) + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + spouse *int + clearedspouse bool +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// SetSpouseID sets the spouse edge to User by id. +func (m *UserMutation) SetSpouseID(id int) { + m.spouse = &id +} + +// ClearSpouse clears the spouse edge to User. +func (m *UserMutation) ClearSpouse() { + m.clearedspouse = true +} + +// SpouseCleared returns if the edge spouse was cleared. +func (m *UserMutation) SpouseCleared() bool { + return m.clearedspouse +} + +// SpouseID returns the spouse id in the mutation. +func (m *UserMutation) SpouseID() (id int, exists bool) { + if m.spouse != nil { + return *m.spouse, true + } + return +} + +// SpouseIDs returns the spouse ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// SpouseID instead. It exists only for internal usage by the builders. +func (m *UserMutation) SpouseIDs() (ids []int) { + if id := m.spouse; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSpouse reset all changes of the spouse edge. +func (m *UserMutation) ResetSpouse() { + m.spouse = nil + m.clearedspouse = false +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.spouse != nil { + edges = append(edges, user.EdgeSpouse) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeSpouse: + if id := m.spouse; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedspouse { + edges = append(edges, user.EdgeSpouse) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + case user.EdgeSpouse: + return m.clearedspouse + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + case user.EdgeSpouse: + m.ClearSpouse() + return nil + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeSpouse: + m.ResetSpouse() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/o2obidi/ent/privacy/privacy.go b/examples/o2obidi/ent/privacy/privacy.go new file mode 100644 index 000000000..51c7ff92f --- /dev/null +++ b/examples/o2obidi/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/o2obidi/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/o2obidi/ent/runtime.go b/examples/o2obidi/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/o2obidi/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/o2obidi/ent/runtime/runtime.go b/examples/o2obidi/ent/runtime/runtime.go new file mode 100644 index 000000000..4d33e904c --- /dev/null +++ b/examples/o2obidi/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/o2obidi/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/o2obidi/ent/tx.go b/examples/o2obidi/ent/tx.go index b6cd96d38..fe30afd5c 100644 --- a/examples/o2obidi/ent/tx.go +++ b/examples/o2obidi/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/o2obidi/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/o2obidi/ent/user/user.go b/examples/o2obidi/ent/user/user.go index 55f2cc248..193e5dce5 100644 --- a/examples/o2obidi/ent/user/user.go +++ b/examples/o2obidi/ent/user/user.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeSpouse holds the string denoting the spouse edge name in mutations. + EdgeSpouse = "spouse" + // Table holds the table name of the user in the database. Table = "users" // SpouseTable is the table the holds the spouse relation/edge. diff --git a/examples/o2obidi/ent/user_create.go b/examples/o2obidi/ent/user_create.go index 4fbac69cb..a1bc7adb6 100644 --- a/examples/o2obidi/ent/user_create.go +++ b/examples/o2obidi/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/o2obidi/ent/user" @@ -18,29 +19,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - spouse map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // SetSpouseID sets the spouse edge to User by id. func (uc *UserCreate) SetSpouseID(id int) *UserCreate { - if uc.spouse == nil { - uc.spouse = make(map[int]struct{}) - } - uc.spouse[id] = struct{}{} + uc.mutation.SetSpouseID(id) return uc } @@ -59,16 +56,36 @@ func (uc *UserCreate) SetSpouse(u *User) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(uc.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } } - return uc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -91,23 +108,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.spouse; len(nodes) > 0 { + if nodes := uc.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -121,7 +138,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2obidi/ent/user_delete.go b/examples/o2obidi/ent/user_delete.go index 464852ceb..366cdbf35 100644 --- a/examples/o2obidi/ent/user_delete.go +++ b/examples/o2obidi/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2obidi/ent/user_update.go b/examples/o2obidi/ent/user_update.go index 183f8a0c4..34ea6dd18 100644 --- a/examples/o2obidi/ent/user_update.go +++ b/examples/o2obidi/ent/user_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,12 +20,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - spouse map[int]struct{} - clearedSpouse bool - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -36,33 +33,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // SetSpouseID sets the spouse edge to User by id. func (uu *UserUpdate) SetSpouseID(id int) *UserUpdate { - if uu.spouse == nil { - uu.spouse = make(map[int]struct{}) - } - uu.spouse[id] = struct{}{} + uu.mutation.SetSpouseID(id) return uu } @@ -81,16 +71,37 @@ func (uu *UserUpdate) SetSpouse(u *User) *UserUpdate { // ClearSpouse clears the spouse edge to User. func (uu *UserUpdate) ClearSpouse() *UserUpdate { - uu.clearedSpouse = true + uu.mutation.ClearSpouse() return uu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if len(uu.spouse) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"spouse\"") + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } } - return uu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -133,28 +144,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if uu.clearedSpouse { + if uu.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -170,7 +181,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.spouse; len(nodes) > 0 { + if nodes := uu.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -184,7 +195,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -203,43 +214,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - spouse map[int]struct{} - clearedSpouse bool + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // SetSpouseID sets the spouse edge to User by id. func (uuo *UserUpdateOne) SetSpouseID(id int) *UserUpdateOne { - if uuo.spouse == nil { - uuo.spouse = make(map[int]struct{}) - } - uuo.spouse[id] = struct{}{} + uuo.mutation.SetSpouseID(id) return uuo } @@ -258,16 +258,37 @@ func (uuo *UserUpdateOne) SetSpouse(u *User) *UserUpdateOne { // ClearSpouse clears the spouse edge to User. func (uuo *UserUpdateOne) ClearSpouse() *UserUpdateOne { - uuo.clearedSpouse = true + uuo.mutation.ClearSpouse() return uuo } // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if len(uuo.spouse) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"spouse\"") + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } } - return uuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -298,34 +319,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if uuo.clearedSpouse { + if uuo.mutation.SpouseCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -341,7 +366,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.spouse; len(nodes) > 0 { + if nodes := uuo.mutation.SpouseIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -355,7 +380,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2orecur/ent/client.go b/examples/o2orecur/ent/client.go index b01c46c29..df2b4c880 100644 --- a/examples/o2orecur/ent/client.go +++ b/examples/o2orecur/ent/client.go @@ -31,13 +31,16 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Node: NewNodeClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Node = NewNodeClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -65,7 +68,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Node: NewNodeClient(cfg), @@ -83,12 +86,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Node: NewNodeClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -96,6 +97,12 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Node.Use(hooks...) +} + // NodeClient is a client for the Node schema. type NodeClient struct { config @@ -106,14 +113,22 @@ func NewNodeClient(c config) *NodeClient { return &NodeClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `node.Hooks(f(g(h())))`. +func (c *NodeClient) Use(hooks ...Hook) { + c.hooks.Node = append(c.hooks.Node, hooks...) +} + // Create returns a create builder for Node. func (c *NodeClient) Create() *NodeCreate { - return &NodeCreate{config: c.config} + mutation := newNodeMutation(c.config, OpCreate) + return &NodeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Node. func (c *NodeClient) Update() *NodeUpdate { - return &NodeUpdate{config: c.config} + mutation := newNodeMutation(c.config, OpUpdate) + return &NodeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -123,12 +138,15 @@ func (c *NodeClient) UpdateOne(n *Node) *NodeUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *NodeClient) UpdateOneID(id int) *NodeUpdateOne { - return &NodeUpdateOne{config: c.config, id: id} + mutation := newNodeMutation(c.config, OpUpdateOne) + mutation.id = &id + return &NodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Node. func (c *NodeClient) Delete() *NodeDelete { - return &NodeDelete{config: c.config} + mutation := newNodeMutation(c.config, OpDelete) + return &NodeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -138,7 +156,10 @@ func (c *NodeClient) DeleteOne(n *Node) *NodeDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *NodeClient) DeleteOneID(id int) *NodeDeleteOne { - return &NodeDeleteOne{c.Delete().Where(node.ID(id))} + builder := c.Delete().Where(node.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &NodeDeleteOne{builder} } // Create returns a query builder for Node. @@ -187,3 +208,8 @@ func (c *NodeClient) QueryNext(n *Node) *NodeQuery { return query } + +// Hooks returns the client hooks. +func (c *NodeClient) Hooks() []Hook { + return c.hooks.Node +} diff --git a/examples/o2orecur/ent/config.go b/examples/o2orecur/ent/config.go index dd64c4cf6..f38504630 100644 --- a/examples/o2orecur/ent/config.go +++ b/examples/o2orecur/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,13 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Node []ent.Hook } // Options applies the options on the config object. diff --git a/examples/o2orecur/ent/ent.go b/examples/o2orecur/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/o2orecur/ent/ent.go +++ b/examples/o2orecur/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/o2orecur/ent/hook/hook.go b/examples/o2orecur/ent/hook/hook.go new file mode 100644 index 000000000..d50fa5f68 --- /dev/null +++ b/examples/o2orecur/ent/hook/hook.go @@ -0,0 +1,61 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/o2orecur/ent" +) + +// The NodeFunc type is an adapter to allow the use of ordinary +// function as Node mutator. +type NodeFunc func(context.Context, *ent.NodeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f NodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.NodeMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/o2orecur/ent/mutation.go b/examples/o2orecur/ent/mutation.go new file mode 100644 index 000000000..4aa2a80ee --- /dev/null +++ b/examples/o2orecur/ent/mutation.go @@ -0,0 +1,412 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/o2orecur/ent/node" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeNode = "Node" +) + +// NodeMutation represents an operation that mutate the Nodes +// nodes in the graph. +type NodeMutation struct { + config + op Op + typ string + id *int + value *int + addvalue *int + clearedFields map[string]bool + prev *int + clearedprev bool + next *int + clearednext bool +} + +var _ ent.Mutation = (*NodeMutation)(nil) + +// newNodeMutation creates new mutation for $n.Name. +func newNodeMutation(c config, op Op) *NodeMutation { + return &NodeMutation{ + config: c, + op: op, + typ: TypeNode, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m NodeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m NodeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *NodeMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetValue sets the value field. +func (m *NodeMutation) SetValue(i int) { + m.value = &i + m.addvalue = nil +} + +// Value returns the value value in the mutation. +func (m *NodeMutation) Value() (r int, exists bool) { + v := m.value + if v == nil { + return + } + return *v, true +} + +// AddValue adds i to value. +func (m *NodeMutation) AddValue(i int) { + if m.addvalue != nil { + *m.addvalue += i + } else { + m.addvalue = &i + } +} + +// AddedValue returns the value that was added to the value field in this mutation. +func (m *NodeMutation) AddedValue() (r int, exists bool) { + v := m.addvalue + if v == nil { + return + } + return *v, true +} + +// ResetValue reset all changes of the value field. +func (m *NodeMutation) ResetValue() { + m.value = nil + m.addvalue = nil +} + +// SetPrevID sets the prev edge to Node by id. +func (m *NodeMutation) SetPrevID(id int) { + m.prev = &id +} + +// ClearPrev clears the prev edge to Node. +func (m *NodeMutation) ClearPrev() { + m.clearedprev = true +} + +// PrevCleared returns if the edge prev was cleared. +func (m *NodeMutation) PrevCleared() bool { + return m.clearedprev +} + +// PrevID returns the prev id in the mutation. +func (m *NodeMutation) PrevID() (id int, exists bool) { + if m.prev != nil { + return *m.prev, true + } + return +} + +// PrevIDs returns the prev ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// PrevID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) PrevIDs() (ids []int) { + if id := m.prev; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetPrev reset all changes of the prev edge. +func (m *NodeMutation) ResetPrev() { + m.prev = nil + m.clearedprev = false +} + +// SetNextID sets the next edge to Node by id. +func (m *NodeMutation) SetNextID(id int) { + m.next = &id +} + +// ClearNext clears the next edge to Node. +func (m *NodeMutation) ClearNext() { + m.clearednext = true +} + +// NextCleared returns if the edge next was cleared. +func (m *NodeMutation) NextCleared() bool { + return m.clearednext +} + +// NextID returns the next id in the mutation. +func (m *NodeMutation) NextID() (id int, exists bool) { + if m.next != nil { + return *m.next, true + } + return +} + +// NextIDs returns the next ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// NextID instead. It exists only for internal usage by the builders. +func (m *NodeMutation) NextIDs() (ids []int) { + if id := m.next; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetNext reset all changes of the next edge. +func (m *NodeMutation) ResetNext() { + m.next = nil + m.clearednext = false +} + +// Op returns the operation name. +func (m *NodeMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Node). +func (m *NodeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *NodeMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.value != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *NodeMutation) Field(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.Value() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) SetField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValue(v) + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *NodeMutation) AddedFields() []string { + var fields []string + if m.addvalue != nil { + fields = append(fields, node.FieldValue) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *NodeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case node.FieldValue: + return m.AddedValue() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *NodeMutation) AddField(name string, value ent.Value) error { + switch name { + case node.FieldValue: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValue(v) + return nil + } + return fmt.Errorf("unknown Node numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *NodeMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *NodeMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *NodeMutation) ClearField(name string) error { + return fmt.Errorf("unknown Node nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *NodeMutation) ResetField(name string) error { + switch name { + case node.FieldValue: + m.ResetValue() + return nil + } + return fmt.Errorf("unknown Node field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *NodeMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.prev != nil { + edges = append(edges, node.EdgePrev) + } + if m.next != nil { + edges = append(edges, node.EdgeNext) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *NodeMutation) AddedIDs(name string) []ent.Value { + switch name { + case node.EdgePrev: + if id := m.prev; id != nil { + return []ent.Value{*id} + } + case node.EdgeNext: + if id := m.next; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *NodeMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *NodeMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *NodeMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedprev { + edges = append(edges, node.EdgePrev) + } + if m.clearednext { + edges = append(edges, node.EdgeNext) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *NodeMutation) EdgeCleared(name string) bool { + switch name { + case node.EdgePrev: + return m.clearedprev + case node.EdgeNext: + return m.clearednext + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *NodeMutation) ClearEdge(name string) error { + switch name { + case node.EdgePrev: + m.ClearPrev() + return nil + case node.EdgeNext: + m.ClearNext() + return nil + } + return fmt.Errorf("unknown Node unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *NodeMutation) ResetEdge(name string) error { + switch name { + case node.EdgePrev: + m.ResetPrev() + return nil + case node.EdgeNext: + m.ResetNext() + return nil + } + return fmt.Errorf("unknown Node edge %s", name) +} diff --git a/examples/o2orecur/ent/node/node.go b/examples/o2orecur/ent/node/node.go index 1b43e0a98..8e88e2e9f 100644 --- a/examples/o2orecur/ent/node/node.go +++ b/examples/o2orecur/ent/node/node.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the node type in the database. Label = "node" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldValue holds the string denoting the value vertex property in the database. + FieldID = "id" // FieldValue holds the string denoting the value vertex property in the database. FieldValue = "value" + // EdgePrev holds the string denoting the prev edge name in mutations. + EdgePrev = "prev" + // EdgeNext holds the string denoting the next edge name in mutations. + EdgeNext = "next" + // Table holds the table name of the node in the database. Table = "nodes" // PrevTable is the table the holds the prev relation/edge. diff --git a/examples/o2orecur/ent/node_create.go b/examples/o2orecur/ent/node_create.go index 6ccd3c227..341488796 100644 --- a/examples/o2orecur/ent/node_create.go +++ b/examples/o2orecur/ent/node_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/o2orecur/ent/node" @@ -18,23 +19,19 @@ import ( // NodeCreate is the builder for creating a Node entity. type NodeCreate struct { config - value *int - prev map[int]struct{} - next map[int]struct{} + mutation *NodeMutation + hooks []Hook } // SetValue sets the value field. func (nc *NodeCreate) SetValue(i int) *NodeCreate { - nc.value = &i + nc.mutation.SetValue(i) return nc } // SetPrevID sets the prev edge to Node by id. func (nc *NodeCreate) SetPrevID(id int) *NodeCreate { - if nc.prev == nil { - nc.prev = make(map[int]struct{}) - } - nc.prev[id] = struct{}{} + nc.mutation.SetPrevID(id) return nc } @@ -53,10 +50,7 @@ func (nc *NodeCreate) SetPrev(n *Node) *NodeCreate { // SetNextID sets the next edge to Node by id. func (nc *NodeCreate) SetNextID(id int) *NodeCreate { - if nc.next == nil { - nc.next = make(map[int]struct{}) - } - nc.next[id] = struct{}{} + nc.mutation.SetNextID(id) return nc } @@ -75,16 +69,33 @@ func (nc *NodeCreate) SetNext(n *Node) *NodeCreate { // Save creates the Node in the database. func (nc *NodeCreate) Save(ctx context.Context) (*Node, error) { - if nc.value == nil { + if _, ok := nc.mutation.Value(); !ok { return nil, errors.New("ent: missing required field \"value\"") } - if len(nc.prev) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"prev\"") + var ( + err error + node *Node + ) + if len(nc.hooks) == 0 { + node, err = nc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nc.mutation = mutation + node, err = nc.sqlSave(ctx) + return node, err + }) + for i := len(nc.hooks); i > 0; i-- { + mut = nc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nc.mutation); err != nil { + return nil, err + } } - if len(nc.next) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -107,15 +118,15 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, } ) - if value := nc.value; value != nil { + if value, ok := nc.mutation.Value(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) - n.Value = *value + n.Value = value } - if nodes := nc.prev; len(nodes) > 0 { + if nodes := nc.mutation.PrevIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -129,12 +140,12 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := nc.next; len(nodes) > 0 { + if nodes := nc.mutation.NextIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -148,7 +159,7 @@ func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/o2orecur/ent/node_delete.go b/examples/o2orecur/ent/node_delete.go index 489ad57d0..0fd39accc 100644 --- a/examples/o2orecur/ent/node_delete.go +++ b/examples/o2orecur/ent/node_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // NodeDelete is the builder for deleting a Node entity. type NodeDelete struct { config + hooks []Hook + mutation *NodeMutation predicates []predicate.Node } @@ -30,7 +33,30 @@ func (nd *NodeDelete) Where(ps ...predicate.Node) *NodeDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (nd *NodeDelete) Exec(ctx context.Context) (int, error) { - return nd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(nd.hooks) == 0 { + affected, err = nd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nd.mutation = mutation + affected, err = nd.sqlExec(ctx) + return affected, err + }) + for i := len(nd.hooks); i > 0; i-- { + mut = nd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/o2orecur/ent/node_update.go b/examples/o2orecur/ent/node_update.go index 3b3129da9..4ae7e3b17 100644 --- a/examples/o2orecur/ent/node_update.go +++ b/examples/o2orecur/ent/node_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,13 +20,9 @@ import ( // NodeUpdate is the builder for updating Node entities. type NodeUpdate struct { config - value *int - addvalue *int - prev map[int]struct{} - next map[int]struct{} - clearedPrev bool - clearedNext bool - predicates []predicate.Node + hooks []Hook + mutation *NodeMutation + predicates []predicate.Node } // Where adds a new predicate for the builder. @@ -37,27 +33,20 @@ func (nu *NodeUpdate) Where(ps ...predicate.Node) *NodeUpdate { // SetValue sets the value field. func (nu *NodeUpdate) SetValue(i int) *NodeUpdate { - nu.value = &i - nu.addvalue = nil + nu.mutation.ResetValue() + nu.mutation.SetValue(i) return nu } // AddValue adds i to value. func (nu *NodeUpdate) AddValue(i int) *NodeUpdate { - if nu.addvalue == nil { - nu.addvalue = &i - } else { - *nu.addvalue += i - } + nu.mutation.AddValue(i) return nu } // SetPrevID sets the prev edge to Node by id. func (nu *NodeUpdate) SetPrevID(id int) *NodeUpdate { - if nu.prev == nil { - nu.prev = make(map[int]struct{}) - } - nu.prev[id] = struct{}{} + nu.mutation.SetPrevID(id) return nu } @@ -76,10 +65,7 @@ func (nu *NodeUpdate) SetPrev(n *Node) *NodeUpdate { // SetNextID sets the next edge to Node by id. func (nu *NodeUpdate) SetNextID(id int) *NodeUpdate { - if nu.next == nil { - nu.next = make(map[int]struct{}) - } - nu.next[id] = struct{}{} + nu.mutation.SetNextID(id) return nu } @@ -98,25 +84,43 @@ func (nu *NodeUpdate) SetNext(n *Node) *NodeUpdate { // ClearPrev clears the prev edge to Node. func (nu *NodeUpdate) ClearPrev() *NodeUpdate { - nu.clearedPrev = true + nu.mutation.ClearPrev() return nu } // ClearNext clears the next edge to Node. func (nu *NodeUpdate) ClearNext() *NodeUpdate { - nu.clearedNext = true + nu.mutation.ClearNext() return nu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (nu *NodeUpdate) Save(ctx context.Context) (int, error) { - if len(nu.prev) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"prev\"") + + var ( + err error + affected int + ) + if len(nu.hooks) == 0 { + affected, err = nu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nu.mutation = mutation + affected, err = nu.sqlSave(ctx) + return affected, err + }) + for i := len(nu.hooks); i > 0; i-- { + mut = nu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nu.mutation); err != nil { + return 0, err + } } - if len(nu.next) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -159,21 +163,21 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := nu.value; value != nil { + if value, ok := nu.mutation.Value(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if value := nu.addvalue; value != nil { + if value, ok := nu.mutation.AddedValue(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if nu.clearedPrev { + if nu.mutation.PrevCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -189,7 +193,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nu.prev; len(nodes) > 0 { + if nodes := nu.mutation.PrevIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -203,12 +207,12 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nu.clearedNext { + if nu.mutation.NextCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -224,7 +228,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nu.next; len(nodes) > 0 { + if nodes := nu.mutation.NextIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -238,7 +242,7 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -257,38 +261,26 @@ func (nu *NodeUpdate) sqlSave(ctx context.Context) (n int, err error) { // NodeUpdateOne is the builder for updating a single Node entity. type NodeUpdateOne struct { config - id int - value *int - addvalue *int - prev map[int]struct{} - next map[int]struct{} - clearedPrev bool - clearedNext bool + hooks []Hook + mutation *NodeMutation } // SetValue sets the value field. func (nuo *NodeUpdateOne) SetValue(i int) *NodeUpdateOne { - nuo.value = &i - nuo.addvalue = nil + nuo.mutation.ResetValue() + nuo.mutation.SetValue(i) return nuo } // AddValue adds i to value. func (nuo *NodeUpdateOne) AddValue(i int) *NodeUpdateOne { - if nuo.addvalue == nil { - nuo.addvalue = &i - } else { - *nuo.addvalue += i - } + nuo.mutation.AddValue(i) return nuo } // SetPrevID sets the prev edge to Node by id. func (nuo *NodeUpdateOne) SetPrevID(id int) *NodeUpdateOne { - if nuo.prev == nil { - nuo.prev = make(map[int]struct{}) - } - nuo.prev[id] = struct{}{} + nuo.mutation.SetPrevID(id) return nuo } @@ -307,10 +299,7 @@ func (nuo *NodeUpdateOne) SetPrev(n *Node) *NodeUpdateOne { // SetNextID sets the next edge to Node by id. func (nuo *NodeUpdateOne) SetNextID(id int) *NodeUpdateOne { - if nuo.next == nil { - nuo.next = make(map[int]struct{}) - } - nuo.next[id] = struct{}{} + nuo.mutation.SetNextID(id) return nuo } @@ -329,25 +318,43 @@ func (nuo *NodeUpdateOne) SetNext(n *Node) *NodeUpdateOne { // ClearPrev clears the prev edge to Node. func (nuo *NodeUpdateOne) ClearPrev() *NodeUpdateOne { - nuo.clearedPrev = true + nuo.mutation.ClearPrev() return nuo } // ClearNext clears the next edge to Node. func (nuo *NodeUpdateOne) ClearNext() *NodeUpdateOne { - nuo.clearedNext = true + nuo.mutation.ClearNext() return nuo } // Save executes the query and returns the updated entity. func (nuo *NodeUpdateOne) Save(ctx context.Context) (*Node, error) { - if len(nuo.prev) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"prev\"") + + var ( + err error + node *Node + ) + if len(nuo.hooks) == 0 { + node, err = nuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*NodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + nuo.mutation = mutation + node, err = nuo.sqlSave(ctx) + return node, err + }) + for i := len(nuo.hooks); i > 0; i-- { + mut = nuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, nuo.mutation); err != nil { + return nil, err + } } - if len(nuo.next) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"next\"") - } - return nuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -378,27 +385,31 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { Table: node.Table, Columns: node.Columns, ID: &sqlgraph.FieldSpec{ - Value: nuo.id, Type: field.TypeInt, Column: node.FieldID, }, }, } - if value := nuo.value; value != nil { + id, ok := nuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Node.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := nuo.mutation.Value(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if value := nuo.addvalue; value != nil { + if value, ok := nuo.mutation.AddedValue(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: node.FieldValue, }) } - if nuo.clearedPrev { + if nuo.mutation.PrevCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -414,7 +425,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nuo.prev; len(nodes) > 0 { + if nodes := nuo.mutation.PrevIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: true, @@ -428,12 +439,12 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nuo.clearedNext { + if nuo.mutation.NextCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -449,7 +460,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := nuo.next; len(nodes) > 0 { + if nodes := nuo.mutation.NextIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, Inverse: false, @@ -463,7 +474,7 @@ func (nuo *NodeUpdateOne) sqlSave(ctx context.Context) (n *Node, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/o2orecur/ent/privacy/privacy.go b/examples/o2orecur/ent/privacy/privacy.go new file mode 100644 index 000000000..56bf35e8e --- /dev/null +++ b/examples/o2orecur/ent/privacy/privacy.go @@ -0,0 +1,171 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/o2orecur/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The NodeReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type NodeReadRuleFunc func(context.Context, *ent.Node) error + +// EvalRead calls f(ctx, v). +func (f NodeReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Node); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Node", v) +} + +// The NodeWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type NodeWriteRuleFunc func(context.Context, *ent.NodeMutation) error + +// EvalWrite calls f(ctx, m). +func (f NodeWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.NodeMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.NodeMutation", m) +} diff --git a/examples/o2orecur/ent/runtime.go b/examples/o2orecur/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/o2orecur/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/o2orecur/ent/runtime/runtime.go b/examples/o2orecur/ent/runtime/runtime.go new file mode 100644 index 000000000..e7869edc6 --- /dev/null +++ b/examples/o2orecur/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/o2orecur/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/o2orecur/ent/tx.go b/examples/o2orecur/ent/tx.go index a5d3a13e9..ea811ee19 100644 --- a/examples/o2orecur/ent/tx.go +++ b/examples/o2orecur/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/o2orecur/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -32,11 +31,13 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Node: NewNodeClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Node = NewNodeClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/start/ent/car/car.go b/examples/start/ent/car/car.go index 79aaac626..00e69924e 100644 --- a/examples/start/ent/car/car.go +++ b/examples/start/ent/car/car.go @@ -10,12 +10,13 @@ const ( // Label holds the string label denoting the car type in the database. Label = "car" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldModel holds the string denoting the model vertex property in the database. - FieldModel = "model" - // FieldRegisteredAt holds the string denoting the registered_at vertex property in the database. + FieldID = "id" // FieldModel holds the string denoting the model vertex property in the database. + FieldModel = "model" // FieldRegisteredAt holds the string denoting the registered_at vertex property in the database. FieldRegisteredAt = "registered_at" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the car in the database. Table = "cars" // OwnerTable is the table the holds the owner relation/edge. diff --git a/examples/start/ent/car_create.go b/examples/start/ent/car_create.go index d86aeaed1..3da103c9e 100644 --- a/examples/start/ent/car_create.go +++ b/examples/start/ent/car_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "time" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -20,29 +21,25 @@ import ( // CarCreate is the builder for creating a Car entity. type CarCreate struct { config - model *string - registered_at *time.Time - owner map[int]struct{} + mutation *CarMutation + hooks []Hook } // SetModel sets the model field. func (cc *CarCreate) SetModel(s string) *CarCreate { - cc.model = &s + cc.mutation.SetModel(s) return cc } // SetRegisteredAt sets the registered_at field. func (cc *CarCreate) SetRegisteredAt(t time.Time) *CarCreate { - cc.registered_at = &t + cc.mutation.SetRegisteredAt(t) return cc } // SetOwnerID sets the owner edge to User by id. func (cc *CarCreate) SetOwnerID(id int) *CarCreate { - if cc.owner == nil { - cc.owner = make(map[int]struct{}) - } - cc.owner[id] = struct{}{} + cc.mutation.SetOwnerID(id) return cc } @@ -61,16 +58,36 @@ func (cc *CarCreate) SetOwner(u *User) *CarCreate { // Save creates the Car in the database. func (cc *CarCreate) Save(ctx context.Context) (*Car, error) { - if cc.model == nil { + if _, ok := cc.mutation.Model(); !ok { return nil, errors.New("ent: missing required field \"model\"") } - if cc.registered_at == nil { + if _, ok := cc.mutation.RegisteredAt(); !ok { return nil, errors.New("ent: missing required field \"registered_at\"") } - if len(cc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Car + ) + if len(cc.hooks) == 0 { + node, err = cc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cc.mutation = mutation + node, err = cc.sqlSave(ctx) + return node, err + }) + for i := len(cc.hooks); i > 0; i-- { + mut = cc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cc.mutation); err != nil { + return nil, err + } } - return cc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -93,23 +110,23 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, } ) - if value := cc.model; value != nil { + if value, ok := cc.mutation.Model(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: car.FieldModel, }) - c.Model = *value + c.Model = value } - if value := cc.registered_at; value != nil { + if value, ok := cc.mutation.RegisteredAt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: car.FieldRegisteredAt, }) - c.RegisteredAt = *value + c.RegisteredAt = value } - if nodes := cc.owner; len(nodes) > 0 { + if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -123,7 +140,7 @@ func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/start/ent/car_delete.go b/examples/start/ent/car_delete.go index de6bb0ae4..23e189b80 100644 --- a/examples/start/ent/car_delete.go +++ b/examples/start/ent/car_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // CarDelete is the builder for deleting a Car entity. type CarDelete struct { config + hooks []Hook + mutation *CarMutation predicates []predicate.Car } @@ -30,7 +33,30 @@ func (cd *CarDelete) Where(ps ...predicate.Car) *CarDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (cd *CarDelete) Exec(ctx context.Context) (int, error) { - return cd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(cd.hooks) == 0 { + affected, err = cd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cd.mutation = mutation + affected, err = cd.sqlExec(ctx) + return affected, err + }) + for i := len(cd.hooks); i > 0; i-- { + mut = cd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/start/ent/car_update.go b/examples/start/ent/car_update.go index 24c3d028a..b0f48157c 100644 --- a/examples/start/ent/car_update.go +++ b/examples/start/ent/car_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "time" "github.com/facebookincubator/ent/dialect/sql" @@ -22,11 +22,9 @@ import ( // CarUpdate is the builder for updating Car entities. type CarUpdate struct { config - model *string - registered_at *time.Time - owner map[int]struct{} - clearedOwner bool - predicates []predicate.Car + hooks []Hook + mutation *CarMutation + predicates []predicate.Car } // Where adds a new predicate for the builder. @@ -37,22 +35,19 @@ func (cu *CarUpdate) Where(ps ...predicate.Car) *CarUpdate { // SetModel sets the model field. func (cu *CarUpdate) SetModel(s string) *CarUpdate { - cu.model = &s + cu.mutation.SetModel(s) return cu } // SetRegisteredAt sets the registered_at field. func (cu *CarUpdate) SetRegisteredAt(t time.Time) *CarUpdate { - cu.registered_at = &t + cu.mutation.SetRegisteredAt(t) return cu } // SetOwnerID sets the owner edge to User by id. func (cu *CarUpdate) SetOwnerID(id int) *CarUpdate { - if cu.owner == nil { - cu.owner = make(map[int]struct{}) - } - cu.owner[id] = struct{}{} + cu.mutation.SetOwnerID(id) return cu } @@ -71,16 +66,37 @@ func (cu *CarUpdate) SetOwner(u *User) *CarUpdate { // ClearOwner clears the owner edge to User. func (cu *CarUpdate) ClearOwner() *CarUpdate { - cu.clearedOwner = true + cu.mutation.ClearOwner() return cu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (cu *CarUpdate) Save(ctx context.Context) (int, error) { - if len(cu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(cu.hooks) == 0 { + affected, err = cu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cu.mutation = mutation + affected, err = cu.sqlSave(ctx) + return affected, err + }) + for i := len(cu.hooks); i > 0; i-- { + mut = cu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cu.mutation); err != nil { + return 0, err + } } - return cu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -123,21 +139,21 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := cu.model; value != nil { + if value, ok := cu.mutation.Model(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: car.FieldModel, }) } - if value := cu.registered_at; value != nil { + if value, ok := cu.mutation.RegisteredAt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: car.FieldRegisteredAt, }) } - if cu.clearedOwner { + if cu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -153,7 +169,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cu.owner; len(nodes) > 0 { + if nodes := cu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -167,7 +183,7 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -186,31 +202,25 @@ func (cu *CarUpdate) sqlSave(ctx context.Context) (n int, err error) { // CarUpdateOne is the builder for updating a single Car entity. type CarUpdateOne struct { config - id int - model *string - registered_at *time.Time - owner map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *CarMutation } // SetModel sets the model field. func (cuo *CarUpdateOne) SetModel(s string) *CarUpdateOne { - cuo.model = &s + cuo.mutation.SetModel(s) return cuo } // SetRegisteredAt sets the registered_at field. func (cuo *CarUpdateOne) SetRegisteredAt(t time.Time) *CarUpdateOne { - cuo.registered_at = &t + cuo.mutation.SetRegisteredAt(t) return cuo } // SetOwnerID sets the owner edge to User by id. func (cuo *CarUpdateOne) SetOwnerID(id int) *CarUpdateOne { - if cuo.owner == nil { - cuo.owner = make(map[int]struct{}) - } - cuo.owner[id] = struct{}{} + cuo.mutation.SetOwnerID(id) return cuo } @@ -229,16 +239,37 @@ func (cuo *CarUpdateOne) SetOwner(u *User) *CarUpdateOne { // ClearOwner clears the owner edge to User. func (cuo *CarUpdateOne) ClearOwner() *CarUpdateOne { - cuo.clearedOwner = true + cuo.mutation.ClearOwner() return cuo } // Save executes the query and returns the updated entity. func (cuo *CarUpdateOne) Save(ctx context.Context) (*Car, error) { - if len(cuo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Car + ) + if len(cuo.hooks) == 0 { + node, err = cuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + cuo.mutation = mutation + node, err = cuo.sqlSave(ctx) + return node, err + }) + for i := len(cuo.hooks); i > 0; i-- { + mut = cuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { + return nil, err + } } - return cuo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -269,27 +300,31 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { Table: car.Table, Columns: car.Columns, ID: &sqlgraph.FieldSpec{ - Value: cuo.id, Type: field.TypeInt, Column: car.FieldID, }, }, } - if value := cuo.model; value != nil { + id, ok := cuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Car.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := cuo.mutation.Model(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: car.FieldModel, }) } - if value := cuo.registered_at; value != nil { + if value, ok := cuo.mutation.RegisteredAt(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeTime, - Value: *value, + Value: value, Column: car.FieldRegisteredAt, }) } - if cuo.clearedOwner { + if cuo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -305,7 +340,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := cuo.owner; len(nodes) > 0 { + if nodes := cuo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -319,7 +354,7 @@ func (cuo *CarUpdateOne) sqlSave(ctx context.Context) (c *Car, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/start/ent/client.go b/examples/start/ent/client.go index 0d61857c0..5dffb8bd7 100644 --- a/examples/start/ent/client.go +++ b/examples/start/ent/client.go @@ -37,15 +37,18 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Car: NewCarClient(c), - Group: NewGroupClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Car = NewCarClient(c.config) + c.Group = NewGroupClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -73,7 +76,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Car: NewCarClient(cfg), @@ -93,14 +96,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Car: NewCarClient(cfg), - Group: NewGroupClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -108,6 +107,14 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Car.Use(hooks...) + c.Group.Use(hooks...) + c.User.Use(hooks...) +} + // CarClient is a client for the Car schema. type CarClient struct { config @@ -118,14 +125,22 @@ func NewCarClient(c config) *CarClient { return &CarClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `car.Hooks(f(g(h())))`. +func (c *CarClient) Use(hooks ...Hook) { + c.hooks.Car = append(c.hooks.Car, hooks...) +} + // Create returns a create builder for Car. func (c *CarClient) Create() *CarCreate { - return &CarCreate{config: c.config} + mutation := newCarMutation(c.config, OpCreate) + return &CarCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Car. func (c *CarClient) Update() *CarUpdate { - return &CarUpdate{config: c.config} + mutation := newCarMutation(c.config, OpUpdate) + return &CarUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -135,12 +150,15 @@ func (c *CarClient) UpdateOne(ca *Car) *CarUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *CarClient) UpdateOneID(id int) *CarUpdateOne { - return &CarUpdateOne{config: c.config, id: id} + mutation := newCarMutation(c.config, OpUpdateOne) + mutation.id = &id + return &CarUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Car. func (c *CarClient) Delete() *CarDelete { - return &CarDelete{config: c.config} + mutation := newCarMutation(c.config, OpDelete) + return &CarDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -150,7 +168,10 @@ func (c *CarClient) DeleteOne(ca *Car) *CarDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *CarClient) DeleteOneID(id int) *CarDeleteOne { - return &CarDeleteOne{c.Delete().Where(car.ID(id))} + builder := c.Delete().Where(car.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &CarDeleteOne{builder} } // Create returns a query builder for Car. @@ -186,6 +207,11 @@ func (c *CarClient) QueryOwner(ca *Car) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *CarClient) Hooks() []Hook { + return c.hooks.Car +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -196,14 +222,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -213,12 +247,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id int) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -228,7 +265,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id int) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -264,6 +304,11 @@ func (c *GroupClient) QueryUsers(gr *Group) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -274,14 +319,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -291,12 +344,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -306,7 +362,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -355,3 +414,8 @@ func (c *UserClient) QueryGroups(u *User) *GroupQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/start/ent/config.go b/examples/start/ent/config.go index dd64c4cf6..9a0727abe 100644 --- a/examples/start/ent/config.go +++ b/examples/start/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,15 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Car []ent.Hook + Group []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/start/ent/ent.go b/examples/start/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/start/ent/ent.go +++ b/examples/start/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/start/ent/group/group.go b/examples/start/ent/group/group.go index f20971a63..9b0ffd04a 100644 --- a/examples/start/ent/group/group.go +++ b/examples/start/ent/group/group.go @@ -6,18 +6,16 @@ package group -import ( - "github.com/facebookincubator/ent/examples/start/ent/schema" -) - const ( // Label holds the string label denoting the group type in the database. Label = "group" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // Table holds the table name of the group in the database. Table = "groups" // UsersTable is the table the holds the users relation/edge. The primary key declared below. @@ -40,10 +38,6 @@ var ( ) var ( - fields = schema.Group{}.Fields() - - // descName is the schema descriptor for name field. - descName = fields[0].Descriptor() // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator = descName.Validators[0].(func(string) error) + NameValidator func(string) error ) diff --git a/examples/start/ent/group_create.go b/examples/start/ent/group_create.go index 1ae0485f2..0370de641 100644 --- a/examples/start/ent/group_create.go +++ b/examples/start/ent/group_create.go @@ -20,24 +20,19 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - name *string - users map[int]struct{} + mutation *GroupMutation + hooks []Hook } // SetName sets the name field. func (gc *GroupCreate) SetName(s string) *GroupCreate { - gc.name = &s + gc.mutation.SetName(s) return gc } // AddUserIDs adds the users edge to User by ids. func (gc *GroupCreate) AddUserIDs(ids ...int) *GroupCreate { - if gc.users == nil { - gc.users = make(map[int]struct{}) - } - for i := range ids { - gc.users[ids[i]] = struct{}{} - } + gc.mutation.AddUserIDs(ids...) return gc } @@ -52,13 +47,38 @@ func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - if gc.name == nil { + if _, ok := gc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if err := group.NameValidator(*gc.name); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + if v, ok := gc.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) + } } - return gc.sqlSave(ctx) + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -81,15 +101,15 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, } ) - if value := gc.name; value != nil { + if value, ok := gc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) - gr.Name = *value + gr.Name = value } - if nodes := gc.users; len(nodes) > 0 { + if nodes := gc.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -103,7 +123,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/start/ent/group_delete.go b/examples/start/ent/group_delete.go index 12a0cf8eb..c0de64448 100644 --- a/examples/start/ent/group_delete.go +++ b/examples/start/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/start/ent/group_update.go b/examples/start/ent/group_update.go index c245adb9a..237f57e44 100644 --- a/examples/start/ent/group_update.go +++ b/examples/start/ent/group_update.go @@ -21,10 +21,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - name *string - users map[int]struct{} - removedUsers map[int]struct{} - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -35,18 +34,13 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // SetName sets the name field. func (gu *GroupUpdate) SetName(s string) *GroupUpdate { - gu.name = &s + gu.mutation.SetName(s) return gu } // AddUserIDs adds the users edge to User by ids. func (gu *GroupUpdate) AddUserIDs(ids ...int) *GroupUpdate { - if gu.users == nil { - gu.users = make(map[int]struct{}) - } - for i := range ids { - gu.users[ids[i]] = struct{}{} - } + gu.mutation.AddUserIDs(ids...) return gu } @@ -61,12 +55,7 @@ func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { // RemoveUserIDs removes the users edge to User by ids. func (gu *GroupUpdate) RemoveUserIDs(ids ...int) *GroupUpdate { - if gu.removedUsers == nil { - gu.removedUsers = make(map[int]struct{}) - } - for i := range ids { - gu.removedUsers[ids[i]] = struct{}{} - } + gu.mutation.RemoveUserIDs(ids...) return gu } @@ -81,12 +70,36 @@ func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - if gu.name != nil { - if err := group.NameValidator(*gu.name); err != nil { + if v, ok := gu.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - return gu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -129,14 +142,14 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := gu.name; value != nil { + if value, ok := gu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := gu.removedUsers; len(nodes) > 0 { + if nodes := gu.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -150,12 +163,12 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.users; len(nodes) > 0 { + if nodes := gu.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -169,7 +182,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -188,26 +201,19 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id int - name *string - users map[int]struct{} - removedUsers map[int]struct{} + hooks []Hook + mutation *GroupMutation } // SetName sets the name field. func (guo *GroupUpdateOne) SetName(s string) *GroupUpdateOne { - guo.name = &s + guo.mutation.SetName(s) return guo } // AddUserIDs adds the users edge to User by ids. func (guo *GroupUpdateOne) AddUserIDs(ids ...int) *GroupUpdateOne { - if guo.users == nil { - guo.users = make(map[int]struct{}) - } - for i := range ids { - guo.users[ids[i]] = struct{}{} - } + guo.mutation.AddUserIDs(ids...) return guo } @@ -222,12 +228,7 @@ func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { // RemoveUserIDs removes the users edge to User by ids. func (guo *GroupUpdateOne) RemoveUserIDs(ids ...int) *GroupUpdateOne { - if guo.removedUsers == nil { - guo.removedUsers = make(map[int]struct{}) - } - for i := range ids { - guo.removedUsers[ids[i]] = struct{}{} - } + guo.mutation.RemoveUserIDs(ids...) return guo } @@ -242,12 +243,36 @@ func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - if guo.name != nil { - if err := group.NameValidator(*guo.name); err != nil { + if v, ok := guo.mutation.Name(); ok { + if err := group.NameValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"name\": %v", err) } } - return guo.sqlSave(ctx) + + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -278,20 +303,24 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeInt, Column: group.FieldID, }, }, } - if value := guo.name; value != nil { + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := guo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := guo.removedUsers; len(nodes) > 0 { + if nodes := guo.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -305,12 +334,12 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.users; len(nodes) > 0 { + if nodes := guo.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -324,7 +353,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/start/ent/hook/hook.go b/examples/start/ent/hook/hook.go new file mode 100644 index 000000000..9b81514cf --- /dev/null +++ b/examples/start/ent/hook/hook.go @@ -0,0 +1,87 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/start/ent" +) + +// The CarFunc type is an adapter to allow the use of ordinary +// function as Car mutator. +type CarFunc func(context.Context, *ent.CarMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f CarFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.CarMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CarMutation", m) + } + return f(ctx, mv) +} + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/start/ent/migrate/schema.go b/examples/start/ent/migrate/schema.go index 21acad3cf..adc53933f 100644 --- a/examples/start/ent/migrate/schema.go +++ b/examples/start/ent/migrate/schema.go @@ -7,8 +7,6 @@ package migrate import ( - "github.com/facebookincubator/ent/examples/start/ent/user" - "github.com/facebookincubator/ent/dialect/sql/schema" "github.com/facebookincubator/ent/schema/field" ) @@ -52,7 +50,7 @@ var ( UsersColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "age", Type: field.TypeInt}, - {Name: "name", Type: field.TypeString, Default: user.DefaultName}, + {Name: "name", Type: field.TypeString, Default: "unknown"}, } // UsersTable holds the schema information for the "users" table. UsersTable = &schema.Table{ diff --git a/examples/start/ent/mutation.go b/examples/start/ent/mutation.go new file mode 100644 index 000000000..126cd122a --- /dev/null +++ b/examples/start/ent/mutation.go @@ -0,0 +1,1087 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "time" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/start/ent/car" + "github.com/facebookincubator/ent/examples/start/ent/group" + "github.com/facebookincubator/ent/examples/start/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeCar = "Car" + TypeGroup = "Group" + TypeUser = "User" +) + +// CarMutation represents an operation that mutate the Cars +// nodes in the graph. +type CarMutation struct { + config + op Op + typ string + id *int + model *string + registered_at *time.Time + clearedFields map[string]bool + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*CarMutation)(nil) + +// newCarMutation creates new mutation for $n.Name. +func newCarMutation(c config, op Op) *CarMutation { + return &CarMutation{ + config: c, + op: op, + typ: TypeCar, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m CarMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m CarMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *CarMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetModel sets the model field. +func (m *CarMutation) SetModel(s string) { + m.model = &s +} + +// Model returns the model value in the mutation. +func (m *CarMutation) Model() (r string, exists bool) { + v := m.model + if v == nil { + return + } + return *v, true +} + +// ResetModel reset all changes of the model field. +func (m *CarMutation) ResetModel() { + m.model = nil +} + +// SetRegisteredAt sets the registered_at field. +func (m *CarMutation) SetRegisteredAt(t time.Time) { + m.registered_at = &t +} + +// RegisteredAt returns the registered_at value in the mutation. +func (m *CarMutation) RegisteredAt() (r time.Time, exists bool) { + v := m.registered_at + if v == nil { + return + } + return *v, true +} + +// ResetRegisteredAt reset all changes of the registered_at field. +func (m *CarMutation) ResetRegisteredAt() { + m.registered_at = nil +} + +// SetOwnerID sets the owner edge to User by id. +func (m *CarMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *CarMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *CarMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *CarMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *CarMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *CarMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *CarMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Car). +func (m *CarMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *CarMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.model != nil { + fields = append(fields, car.FieldModel) + } + if m.registered_at != nil { + fields = append(fields, car.FieldRegisteredAt) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *CarMutation) Field(name string) (ent.Value, bool) { + switch name { + case car.FieldModel: + return m.Model() + case car.FieldRegisteredAt: + return m.RegisteredAt() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) SetField(name string, value ent.Value) error { + switch name { + case car.FieldModel: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetModel(v) + return nil + case car.FieldRegisteredAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRegisteredAt(v) + return nil + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *CarMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *CarMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *CarMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Car numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *CarMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *CarMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *CarMutation) ClearField(name string) error { + return fmt.Errorf("unknown Car nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *CarMutation) ResetField(name string) error { + switch name { + case car.FieldModel: + m.ResetModel() + return nil + case car.FieldRegisteredAt: + m.ResetRegisteredAt() + return nil + } + return fmt.Errorf("unknown Car field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *CarMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.owner != nil { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *CarMutation) AddedIDs(name string) []ent.Value { + switch name { + case car.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *CarMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *CarMutation) RemovedIDs(name string) []ent.Value { + switch name { + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *CarMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedowner { + edges = append(edges, car.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *CarMutation) EdgeCleared(name string) bool { + switch name { + case car.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *CarMutation) ClearEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Car unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *CarMutation) ResetEdge(name string) error { + switch name { + case car.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Car edge %s", name) +} + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + users map[int]struct{} + removedusers map[int]struct{} +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *GroupMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *GroupMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *GroupMutation) ResetName() { + m.name = nil +} + +// AddUserIDs adds the users edge to User by ids. +func (m *GroupMutation) AddUserIDs(ids ...int) { + if m.users == nil { + m.users = make(map[int]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// RemoveUserIDs removes the users edge to User by ids. +func (m *GroupMutation) RemoveUserIDs(ids ...int) { + if m.removedusers == nil { + m.removedusers = make(map[int]struct{}) + } + for i := range ids { + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed ids of users. +func (m *GroupMutation) RemovedUsersIDs() (ids []int) { + for id := range m.removedusers { + ids = append(ids, id) + } + return +} + +// UsersIDs returns the users ids in the mutation. +func (m *GroupMutation) UsersIDs() (ids []int) { + for id := range m.users { + ids = append(ids, id) + } + return +} + +// ResetUsers reset all changes of the users edge. +func (m *GroupMutation) ResetUsers() { + m.users = nil + m.removedusers = nil +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, group.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + case group.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + case group.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + case group.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.users != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedusers != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + case group.EdgeUsers: + m.ResetUsers() + return nil + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + cars map[int]struct{} + removedcars map[int]struct{} + groups map[int]struct{} + removedgroups map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddCarIDs adds the cars edge to Car by ids. +func (m *UserMutation) AddCarIDs(ids ...int) { + if m.cars == nil { + m.cars = make(map[int]struct{}) + } + for i := range ids { + m.cars[ids[i]] = struct{}{} + } +} + +// RemoveCarIDs removes the cars edge to Car by ids. +func (m *UserMutation) RemoveCarIDs(ids ...int) { + if m.removedcars == nil { + m.removedcars = make(map[int]struct{}) + } + for i := range ids { + m.removedcars[ids[i]] = struct{}{} + } +} + +// RemovedCars returns the removed ids of cars. +func (m *UserMutation) RemovedCarsIDs() (ids []int) { + for id := range m.removedcars { + ids = append(ids, id) + } + return +} + +// CarsIDs returns the cars ids in the mutation. +func (m *UserMutation) CarsIDs() (ids []int) { + for id := range m.cars { + ids = append(ids, id) + } + return +} + +// ResetCars reset all changes of the cars edge. +func (m *UserMutation) ResetCars() { + m.cars = nil + m.removedcars = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *UserMutation) AddGroupIDs(ids ...int) { + if m.groups == nil { + m.groups = make(map[int]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *UserMutation) RemoveGroupIDs(ids ...int) { + if m.removedgroups == nil { + m.removedgroups = make(map[int]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *UserMutation) RemovedGroupsIDs() (ids []int) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *UserMutation) GroupsIDs() (ids []int) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *UserMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.cars != nil { + edges = append(edges, user.EdgeCars) + } + if m.groups != nil { + edges = append(edges, user.EdgeGroups) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgeCars: + ids := make([]ent.Value, 0, len(m.cars)) + for id := range m.cars { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedcars != nil { + edges = append(edges, user.EdgeCars) + } + if m.removedgroups != nil { + edges = append(edges, user.EdgeGroups) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgeCars: + ids := make([]ent.Value, 0, len(m.removedcars)) + for id := range m.removedcars { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgeCars: + m.ResetCars() + return nil + case user.EdgeGroups: + m.ResetGroups() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/start/ent/privacy/privacy.go b/examples/start/ent/privacy/privacy.go new file mode 100644 index 000000000..d89909e46 --- /dev/null +++ b/examples/start/ent/privacy/privacy.go @@ -0,0 +1,219 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/start/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The CarReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type CarReadRuleFunc func(context.Context, *ent.Car) error + +// EvalRead calls f(ctx, v). +func (f CarReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Car); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Car", v) +} + +// The CarWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type CarWriteRuleFunc func(context.Context, *ent.CarMutation) error + +// EvalWrite calls f(ctx, m). +func (f CarWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.CarMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.CarMutation", m) +} + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/start/ent/runtime.go b/examples/start/ent/runtime.go new file mode 100644 index 000000000..e5cf5c713 --- /dev/null +++ b/examples/start/ent/runtime.go @@ -0,0 +1,35 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "github.com/facebookincubator/ent/examples/start/ent/schema" + + "github.com/facebookincubator/ent/examples/start/ent/group" + + "github.com/facebookincubator/ent/examples/start/ent/user" +) + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { + groupFields := schema.Group{}.Fields() + // groupDescName is the schema descriptor for name field. + groupDescName := groupFields[0].Descriptor() + // group.NameValidator is a validator for the "name" field. It is called by the builders before save. + group.NameValidator = groupDescName.Validators[0].(func(string) error) + userFields := schema.User{}.Fields() + // userDescAge is the schema descriptor for age field. + userDescAge := userFields[0].Descriptor() + // user.AgeValidator is a validator for the "age" field. It is called by the builders before save. + user.AgeValidator = userDescAge.Validators[0].(func(int) error) + // userDescName is the schema descriptor for name field. + userDescName := userFields[1].Descriptor() + // user.DefaultName holds the default value on creation for the name field. + user.DefaultName = userDescName.Default.(string) +} diff --git a/examples/start/ent/runtime/runtime.go b/examples/start/ent/runtime/runtime.go new file mode 100644 index 000000000..d4a5a92e6 --- /dev/null +++ b/examples/start/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/start/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/start/ent/tx.go b/examples/start/ent/tx.go index d0255131d..1c52d9aa9 100644 --- a/examples/start/ent/tx.go +++ b/examples/start/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/start/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -36,13 +35,15 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Car: NewCarClient(tx.config), - Group: NewGroupClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Car = NewCarClient(tx.config) + tx.Group = NewGroupClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/start/ent/user/user.go b/examples/start/ent/user/user.go index d951eaa7b..dfa494bdb 100644 --- a/examples/start/ent/user/user.go +++ b/examples/start/ent/user/user.go @@ -6,20 +6,19 @@ package user -import ( - "github.com/facebookincubator/ent/examples/start/ent/schema" -) - const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeCars holds the string denoting the cars edge name in mutations. + EdgeCars = "cars" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // Table holds the table name of the user in the database. Table = "users" // CarsTable is the table the holds the cars relation/edge. @@ -50,15 +49,8 @@ var ( ) var ( - fields = schema.User{}.Fields() - - // descAge is the schema descriptor for age field. - descAge = fields[0].Descriptor() // AgeValidator is a validator for the "age" field. It is called by the builders before save. - AgeValidator = descAge.Validators[0].(func(int) error) - - // descName is the schema descriptor for name field. - descName = fields[1].Descriptor() + AgeValidator func(int) error // DefaultName holds the default value on creation for the name field. - DefaultName = descName.Default.(string) + DefaultName string ) diff --git a/examples/start/ent/user_create.go b/examples/start/ent/user_create.go index 3f9cfa71b..eeb0661a5 100644 --- a/examples/start/ent/user_create.go +++ b/examples/start/ent/user_create.go @@ -21,21 +21,19 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - cars map[int]struct{} - groups map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } @@ -49,12 +47,7 @@ func (uc *UserCreate) SetNillableName(s *string) *UserCreate { // AddCarIDs adds the cars edge to Car by ids. func (uc *UserCreate) AddCarIDs(ids ...int) *UserCreate { - if uc.cars == nil { - uc.cars = make(map[int]struct{}) - } - for i := range ids { - uc.cars[ids[i]] = struct{}{} - } + uc.mutation.AddCarIDs(ids...) return uc } @@ -69,12 +62,7 @@ func (uc *UserCreate) AddCars(c ...*Car) *UserCreate { // AddGroupIDs adds the groups edge to Group by ids. func (uc *UserCreate) AddGroupIDs(ids ...int) *UserCreate { - if uc.groups == nil { - uc.groups = make(map[int]struct{}) - } - for i := range ids { - uc.groups[ids[i]] = struct{}{} - } + uc.mutation.AddGroupIDs(ids...) return uc } @@ -89,17 +77,42 @@ func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if err := user.AgeValidator(*uc.age); err != nil { - return nil, fmt.Errorf("ent: validator failed for field \"age\": %v", err) + if v, ok := uc.mutation.Age(); ok { + if err := user.AgeValidator(v); err != nil { + return nil, fmt.Errorf("ent: validator failed for field \"age\": %v", err) + } } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { v := user.DefaultName - uc.name = &v + uc.mutation.SetName(v) } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -122,23 +135,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.cars; len(nodes) > 0 { + if nodes := uc.mutation.CarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -152,12 +165,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.groups; len(nodes) > 0 { + if nodes := uc.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -171,7 +184,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/start/ent/user_delete.go b/examples/start/ent/user_delete.go index ff06e0051..506822640 100644 --- a/examples/start/ent/user_delete.go +++ b/examples/start/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/start/ent/user_update.go b/examples/start/ent/user_update.go index e5be0f62c..5f96a85f7 100644 --- a/examples/start/ent/user_update.go +++ b/examples/start/ent/user_update.go @@ -22,14 +22,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - cars map[int]struct{} - groups map[int]struct{} - removedCars map[int]struct{} - removedGroups map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -40,24 +35,20 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } @@ -71,12 +62,7 @@ func (uu *UserUpdate) SetNillableName(s *string) *UserUpdate { // AddCarIDs adds the cars edge to Car by ids. func (uu *UserUpdate) AddCarIDs(ids ...int) *UserUpdate { - if uu.cars == nil { - uu.cars = make(map[int]struct{}) - } - for i := range ids { - uu.cars[ids[i]] = struct{}{} - } + uu.mutation.AddCarIDs(ids...) return uu } @@ -91,12 +77,7 @@ func (uu *UserUpdate) AddCars(c ...*Car) *UserUpdate { // AddGroupIDs adds the groups edge to Group by ids. func (uu *UserUpdate) AddGroupIDs(ids ...int) *UserUpdate { - if uu.groups == nil { - uu.groups = make(map[int]struct{}) - } - for i := range ids { - uu.groups[ids[i]] = struct{}{} - } + uu.mutation.AddGroupIDs(ids...) return uu } @@ -111,12 +92,7 @@ func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { // RemoveCarIDs removes the cars edge to Car by ids. func (uu *UserUpdate) RemoveCarIDs(ids ...int) *UserUpdate { - if uu.removedCars == nil { - uu.removedCars = make(map[int]struct{}) - } - for i := range ids { - uu.removedCars[ids[i]] = struct{}{} - } + uu.mutation.RemoveCarIDs(ids...) return uu } @@ -131,12 +107,7 @@ func (uu *UserUpdate) RemoveCars(c ...*Car) *UserUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (uu *UserUpdate) RemoveGroupIDs(ids ...int) *UserUpdate { - if uu.removedGroups == nil { - uu.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uu.removedGroups[ids[i]] = struct{}{} - } + uu.mutation.RemoveGroupIDs(ids...) return uu } @@ -151,12 +122,36 @@ func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - if uu.age != nil { - if err := user.AgeValidator(*uu.age); err != nil { + if v, ok := uu.mutation.Age(); ok { + if err := user.AgeValidator(v); err != nil { return 0, fmt.Errorf("ent: validator failed for field \"age\": %v", err) } } - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -199,28 +194,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedCars; len(nodes) > 0 { + if nodes := uu.mutation.RemovedCarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -234,12 +229,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.cars; len(nodes) > 0 { + if nodes := uu.mutation.CarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -253,12 +248,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedGroups; len(nodes) > 0 { + if nodes := uu.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -272,12 +267,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.groups; len(nodes) > 0 { + if nodes := uu.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -291,7 +286,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -310,36 +305,26 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - cars map[int]struct{} - groups map[int]struct{} - removedCars map[int]struct{} - removedGroups map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } @@ -353,12 +338,7 @@ func (uuo *UserUpdateOne) SetNillableName(s *string) *UserUpdateOne { // AddCarIDs adds the cars edge to Car by ids. func (uuo *UserUpdateOne) AddCarIDs(ids ...int) *UserUpdateOne { - if uuo.cars == nil { - uuo.cars = make(map[int]struct{}) - } - for i := range ids { - uuo.cars[ids[i]] = struct{}{} - } + uuo.mutation.AddCarIDs(ids...) return uuo } @@ -373,12 +353,7 @@ func (uuo *UserUpdateOne) AddCars(c ...*Car) *UserUpdateOne { // AddGroupIDs adds the groups edge to Group by ids. func (uuo *UserUpdateOne) AddGroupIDs(ids ...int) *UserUpdateOne { - if uuo.groups == nil { - uuo.groups = make(map[int]struct{}) - } - for i := range ids { - uuo.groups[ids[i]] = struct{}{} - } + uuo.mutation.AddGroupIDs(ids...) return uuo } @@ -393,12 +368,7 @@ func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { // RemoveCarIDs removes the cars edge to Car by ids. func (uuo *UserUpdateOne) RemoveCarIDs(ids ...int) *UserUpdateOne { - if uuo.removedCars == nil { - uuo.removedCars = make(map[int]struct{}) - } - for i := range ids { - uuo.removedCars[ids[i]] = struct{}{} - } + uuo.mutation.RemoveCarIDs(ids...) return uuo } @@ -413,12 +383,7 @@ func (uuo *UserUpdateOne) RemoveCars(c ...*Car) *UserUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...int) *UserUpdateOne { - if uuo.removedGroups == nil { - uuo.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uuo.removedGroups[ids[i]] = struct{}{} - } + uuo.mutation.RemoveGroupIDs(ids...) return uuo } @@ -433,12 +398,36 @@ func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - if uuo.age != nil { - if err := user.AgeValidator(*uuo.age); err != nil { + if v, ok := uuo.mutation.Age(); ok { + if err := user.AgeValidator(v); err != nil { return nil, fmt.Errorf("ent: validator failed for field \"age\": %v", err) } } - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -469,34 +458,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedCars; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedCarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -510,12 +503,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.cars; len(nodes) > 0 { + if nodes := uuo.mutation.CarsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -529,12 +522,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedGroups; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -548,12 +541,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.groups; len(nodes) > 0 { + if nodes := uuo.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -567,7 +560,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/traversal/ent/client.go b/examples/traversal/ent/client.go index 48da43f0d..01321374d 100644 --- a/examples/traversal/ent/client.go +++ b/examples/traversal/ent/client.go @@ -37,15 +37,18 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - c := config{log: log.Println} - c.options(opts...) - return &Client{ - config: c, - Schema: migrate.NewSchema(c.driver), - Group: NewGroupClient(c), - Pet: NewPetClient(c), - User: NewUserClient(c), - } + cfg := config{log: log.Println, hooks: &hooks{}} + cfg.options(opts...) + client := &Client{config: cfg} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Group = NewGroupClient(c.config) + c.Pet = NewPetClient(c.config) + c.User = NewUserClient(c.config) } // Open opens a connection to the database specified by the driver name and a @@ -73,7 +76,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %v", err) } - cfg := config{driver: tx, log: c.log, debug: c.debug} + cfg := config{driver: tx, log: c.log, debug: c.debug, hooks: c.hooks} return &Tx{ config: cfg, Group: NewGroupClient(cfg), @@ -93,14 +96,10 @@ func (c *Client) Debug() *Client { if c.debug { return c } - cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} - return &Client{ - config: cfg, - Schema: migrate.NewSchema(cfg.driver), - Group: NewGroupClient(cfg), - Pet: NewPetClient(cfg), - User: NewUserClient(cfg), - } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks} + client := &Client{config: cfg} + client.init() + return client } // Close closes the database connection and prevents new queries from starting. @@ -108,6 +107,14 @@ func (c *Client) Close() error { return c.driver.Close() } +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Group.Use(hooks...) + c.Pet.Use(hooks...) + c.User.Use(hooks...) +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -118,14 +125,22 @@ func NewGroupClient(c config) *GroupClient { return &GroupClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `group.Hooks(f(g(h())))`. +func (c *GroupClient) Use(hooks ...Hook) { + c.hooks.Group = append(c.hooks.Group, hooks...) +} + // Create returns a create builder for Group. func (c *GroupClient) Create() *GroupCreate { - return &GroupCreate{config: c.config} + mutation := newGroupMutation(c.config, OpCreate) + return &GroupCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Group. func (c *GroupClient) Update() *GroupUpdate { - return &GroupUpdate{config: c.config} + mutation := newGroupMutation(c.config, OpUpdate) + return &GroupUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -135,12 +150,15 @@ func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *GroupClient) UpdateOneID(id int) *GroupUpdateOne { - return &GroupUpdateOne{config: c.config, id: id} + mutation := newGroupMutation(c.config, OpUpdateOne) + mutation.id = &id + return &GroupUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Group. func (c *GroupClient) Delete() *GroupDelete { - return &GroupDelete{config: c.config} + mutation := newGroupMutation(c.config, OpDelete) + return &GroupDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -150,7 +168,10 @@ func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *GroupClient) DeleteOneID(id int) *GroupDeleteOne { - return &GroupDeleteOne{c.Delete().Where(group.ID(id))} + builder := c.Delete().Where(group.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &GroupDeleteOne{builder} } // Create returns a query builder for Group. @@ -200,6 +221,11 @@ func (c *GroupClient) QueryAdmin(gr *Group) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *GroupClient) Hooks() []Hook { + return c.hooks.Group +} + // PetClient is a client for the Pet schema. type PetClient struct { config @@ -210,14 +236,22 @@ func NewPetClient(c config) *PetClient { return &PetClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `pet.Hooks(f(g(h())))`. +func (c *PetClient) Use(hooks ...Hook) { + c.hooks.Pet = append(c.hooks.Pet, hooks...) +} + // Create returns a create builder for Pet. func (c *PetClient) Create() *PetCreate { - return &PetCreate{config: c.config} + mutation := newPetMutation(c.config, OpCreate) + return &PetCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for Pet. func (c *PetClient) Update() *PetUpdate { - return &PetUpdate{config: c.config} + mutation := newPetMutation(c.config, OpUpdate) + return &PetUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -227,12 +261,15 @@ func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *PetClient) UpdateOneID(id int) *PetUpdateOne { - return &PetUpdateOne{config: c.config, id: id} + mutation := newPetMutation(c.config, OpUpdateOne) + mutation.id = &id + return &PetUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for Pet. func (c *PetClient) Delete() *PetDelete { - return &PetDelete{config: c.config} + mutation := newPetMutation(c.config, OpDelete) + return &PetDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -242,7 +279,10 @@ func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *PetClient) DeleteOneID(id int) *PetDeleteOne { - return &PetDeleteOne{c.Delete().Where(pet.ID(id))} + builder := c.Delete().Where(pet.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PetDeleteOne{builder} } // Create returns a query builder for Pet. @@ -292,6 +332,11 @@ func (c *PetClient) QueryOwner(pe *Pet) *UserQuery { return query } +// Hooks returns the client hooks. +func (c *PetClient) Hooks() []Hook { + return c.hooks.Pet +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -302,14 +347,22 @@ func NewUserClient(c config) *UserClient { return &UserClient{config: c} } +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. +func (c *UserClient) Use(hooks ...Hook) { + c.hooks.User = append(c.hooks.User, hooks...) +} + // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { - return &UserCreate{config: c.config} + mutation := newUserMutation(c.config, OpCreate) + return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { - return &UserUpdate{config: c.config} + mutation := newUserMutation(c.config, OpUpdate) + return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. @@ -319,12 +372,15 @@ func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - return &UserUpdateOne{config: c.config, id: id} + mutation := newUserMutation(c.config, OpUpdateOne) + mutation.id = &id + return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { - return &UserDelete{config: c.config} + mutation := newUserMutation(c.config, OpDelete) + return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. @@ -334,7 +390,10 @@ func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - return &UserDeleteOne{c.Delete().Where(user.ID(id))} + builder := c.Delete().Where(user.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserDeleteOne{builder} } // Create returns a query builder for User. @@ -411,3 +470,8 @@ func (c *UserClient) QueryManage(u *User) *GroupQuery { return query } + +// Hooks returns the client hooks. +func (c *UserClient) Hooks() []Hook { + return c.hooks.User +} diff --git a/examples/traversal/ent/config.go b/examples/traversal/ent/config.go index dd64c4cf6..34dab2204 100644 --- a/examples/traversal/ent/config.go +++ b/examples/traversal/ent/config.go @@ -7,6 +7,7 @@ package ent import ( + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" ) @@ -21,6 +22,15 @@ type config struct { debug bool // log used for logging on debug mode. log func(...interface{}) + // hooks to execute on mutations. + hooks *hooks +} + +// hooks per client, for fast access. +type hooks struct { + Group []ent.Hook + Pet []ent.Hook + User []ent.Hook } // Options applies the options on the config object. diff --git a/examples/traversal/ent/ent.go b/examples/traversal/ent/ent.go index 3c71a475d..468ee7ba7 100644 --- a/examples/traversal/ent/ent.go +++ b/examples/traversal/ent/ent.go @@ -11,12 +11,23 @@ import ( "fmt" "strings" + "github.com/facebookincubator/ent" "github.com/facebookincubator/ent/dialect" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "golang.org/x/xerrors" ) +// ent aliases to avoid import conflict in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + // Order applies an ordering on either graph traversal or sql selector. type Order func(*sql.Selector) diff --git a/examples/traversal/ent/group/group.go b/examples/traversal/ent/group/group.go index e8b68ca70..e1040ec82 100644 --- a/examples/traversal/ent/group/group.go +++ b/examples/traversal/ent/group/group.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the group type in the database. Label = "group" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // EdgeAdmin holds the string denoting the admin edge name in mutations. + EdgeAdmin = "admin" + // Table holds the table name of the group in the database. Table = "groups" // UsersTable is the table the holds the users relation/edge. The primary key declared below. diff --git a/examples/traversal/ent/group_create.go b/examples/traversal/ent/group_create.go index 722102dc4..a83c230f2 100644 --- a/examples/traversal/ent/group_create.go +++ b/examples/traversal/ent/group_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/traversal/ent/group" @@ -19,25 +20,19 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - name *string - users map[int]struct{} - admin map[int]struct{} + mutation *GroupMutation + hooks []Hook } // SetName sets the name field. func (gc *GroupCreate) SetName(s string) *GroupCreate { - gc.name = &s + gc.mutation.SetName(s) return gc } // AddUserIDs adds the users edge to User by ids. func (gc *GroupCreate) AddUserIDs(ids ...int) *GroupCreate { - if gc.users == nil { - gc.users = make(map[int]struct{}) - } - for i := range ids { - gc.users[ids[i]] = struct{}{} - } + gc.mutation.AddUserIDs(ids...) return gc } @@ -52,10 +47,7 @@ func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { // SetAdminID sets the admin edge to User by id. func (gc *GroupCreate) SetAdminID(id int) *GroupCreate { - if gc.admin == nil { - gc.admin = make(map[int]struct{}) - } - gc.admin[id] = struct{}{} + gc.mutation.SetAdminID(id) return gc } @@ -74,13 +66,33 @@ func (gc *GroupCreate) SetAdmin(u *User) *GroupCreate { // Save creates the Group in the database. func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { - if gc.name == nil { + if _, ok := gc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(gc.admin) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"admin\"") + var ( + err error + node *Group + ) + if len(gc.hooks) == 0 { + node, err = gc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gc.mutation = mutation + node, err = gc.sqlSave(ctx) + return node, err + }) + for i := len(gc.hooks); i > 0; i-- { + mut = gc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gc.mutation); err != nil { + return nil, err + } } - return gc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -103,15 +115,15 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, } ) - if value := gc.name; value != nil { + if value, ok := gc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) - gr.Name = *value + gr.Name = value } - if nodes := gc.users; len(nodes) > 0 { + if nodes := gc.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -125,12 +137,12 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := gc.admin; len(nodes) > 0 { + if nodes := gc.mutation.AdminIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -144,7 +156,7 @@ func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/traversal/ent/group_delete.go b/examples/traversal/ent/group_delete.go index f27f678d2..832e88550 100644 --- a/examples/traversal/ent/group_delete.go +++ b/examples/traversal/ent/group_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config + hooks []Hook + mutation *GroupMutation predicates []predicate.Group } @@ -30,7 +33,30 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { - return gd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(gd.hooks) == 0 { + affected, err = gd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gd.mutation = mutation + affected, err = gd.sqlExec(ctx) + return affected, err + }) + for i := len(gd.hooks); i > 0; i-- { + mut = gd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/traversal/ent/group_update.go b/examples/traversal/ent/group_update.go index 77c4da05f..d95518a5c 100644 --- a/examples/traversal/ent/group_update.go +++ b/examples/traversal/ent/group_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,12 +21,9 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - name *string - users map[int]struct{} - admin map[int]struct{} - removedUsers map[int]struct{} - clearedAdmin bool - predicates []predicate.Group + hooks []Hook + mutation *GroupMutation + predicates []predicate.Group } // Where adds a new predicate for the builder. @@ -37,18 +34,13 @@ func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { // SetName sets the name field. func (gu *GroupUpdate) SetName(s string) *GroupUpdate { - gu.name = &s + gu.mutation.SetName(s) return gu } // AddUserIDs adds the users edge to User by ids. func (gu *GroupUpdate) AddUserIDs(ids ...int) *GroupUpdate { - if gu.users == nil { - gu.users = make(map[int]struct{}) - } - for i := range ids { - gu.users[ids[i]] = struct{}{} - } + gu.mutation.AddUserIDs(ids...) return gu } @@ -63,10 +55,7 @@ func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { // SetAdminID sets the admin edge to User by id. func (gu *GroupUpdate) SetAdminID(id int) *GroupUpdate { - if gu.admin == nil { - gu.admin = make(map[int]struct{}) - } - gu.admin[id] = struct{}{} + gu.mutation.SetAdminID(id) return gu } @@ -85,12 +74,7 @@ func (gu *GroupUpdate) SetAdmin(u *User) *GroupUpdate { // RemoveUserIDs removes the users edge to User by ids. func (gu *GroupUpdate) RemoveUserIDs(ids ...int) *GroupUpdate { - if gu.removedUsers == nil { - gu.removedUsers = make(map[int]struct{}) - } - for i := range ids { - gu.removedUsers[ids[i]] = struct{}{} - } + gu.mutation.RemoveUserIDs(ids...) return gu } @@ -105,16 +89,37 @@ func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { // ClearAdmin clears the admin edge to User. func (gu *GroupUpdate) ClearAdmin() *GroupUpdate { - gu.clearedAdmin = true + gu.mutation.ClearAdmin() return gu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { - if len(gu.admin) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"admin\"") + + var ( + err error + affected int + ) + if len(gu.hooks) == 0 { + affected, err = gu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + gu.mutation = mutation + affected, err = gu.sqlSave(ctx) + return affected, err + }) + for i := len(gu.hooks); i > 0; i-- { + mut = gu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, gu.mutation); err != nil { + return 0, err + } } - return gu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -157,14 +162,14 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := gu.name; value != nil { + if value, ok := gu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := gu.removedUsers; len(nodes) > 0 { + if nodes := gu.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -178,12 +183,12 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.users; len(nodes) > 0 { + if nodes := gu.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -197,12 +202,12 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if gu.clearedAdmin { + if gu.mutation.AdminCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -218,7 +223,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := gu.admin; len(nodes) > 0 { + if nodes := gu.mutation.AdminIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -232,7 +237,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -251,28 +256,19 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - id int - name *string - users map[int]struct{} - admin map[int]struct{} - removedUsers map[int]struct{} - clearedAdmin bool + hooks []Hook + mutation *GroupMutation } // SetName sets the name field. func (guo *GroupUpdateOne) SetName(s string) *GroupUpdateOne { - guo.name = &s + guo.mutation.SetName(s) return guo } // AddUserIDs adds the users edge to User by ids. func (guo *GroupUpdateOne) AddUserIDs(ids ...int) *GroupUpdateOne { - if guo.users == nil { - guo.users = make(map[int]struct{}) - } - for i := range ids { - guo.users[ids[i]] = struct{}{} - } + guo.mutation.AddUserIDs(ids...) return guo } @@ -287,10 +283,7 @@ func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { // SetAdminID sets the admin edge to User by id. func (guo *GroupUpdateOne) SetAdminID(id int) *GroupUpdateOne { - if guo.admin == nil { - guo.admin = make(map[int]struct{}) - } - guo.admin[id] = struct{}{} + guo.mutation.SetAdminID(id) return guo } @@ -309,12 +302,7 @@ func (guo *GroupUpdateOne) SetAdmin(u *User) *GroupUpdateOne { // RemoveUserIDs removes the users edge to User by ids. func (guo *GroupUpdateOne) RemoveUserIDs(ids ...int) *GroupUpdateOne { - if guo.removedUsers == nil { - guo.removedUsers = make(map[int]struct{}) - } - for i := range ids { - guo.removedUsers[ids[i]] = struct{}{} - } + guo.mutation.RemoveUserIDs(ids...) return guo } @@ -329,16 +317,37 @@ func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { // ClearAdmin clears the admin edge to User. func (guo *GroupUpdateOne) ClearAdmin() *GroupUpdateOne { - guo.clearedAdmin = true + guo.mutation.ClearAdmin() return guo } // Save executes the query and returns the updated entity. func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { - if len(guo.admin) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"admin\"") + + var ( + err error + node *Group + ) + if len(guo.hooks) == 0 { + node, err = guo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + guo.mutation = mutation + node, err = guo.sqlSave(ctx) + return node, err + }) + for i := len(guo.hooks); i > 0; i-- { + mut = guo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, guo.mutation); err != nil { + return nil, err + } } - return guo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -369,20 +378,24 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { Table: group.Table, Columns: group.Columns, ID: &sqlgraph.FieldSpec{ - Value: guo.id, Type: field.TypeInt, Column: group.FieldID, }, }, } - if value := guo.name; value != nil { + id, ok := guo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Group.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := guo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: group.FieldName, }) } - if nodes := guo.removedUsers; len(nodes) > 0 { + if nodes := guo.mutation.RemovedUsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -396,12 +409,12 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.users; len(nodes) > 0 { + if nodes := guo.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -415,12 +428,12 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if guo.clearedAdmin { + if guo.mutation.AdminCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -436,7 +449,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := guo.admin; len(nodes) > 0 { + if nodes := guo.mutation.AdminIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: false, @@ -450,7 +463,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/traversal/ent/hook/hook.go b/examples/traversal/ent/hook/hook.go new file mode 100644 index 000000000..528637fc0 --- /dev/null +++ b/examples/traversal/ent/hook/hook.go @@ -0,0 +1,87 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/examples/traversal/ent" +) + +// The GroupFunc type is an adapter to allow the use of ordinary +// function as Group mutator. +type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f GroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.GroupMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GroupMutation", m) + } + return f(ctx, mv) +} + +// The PetFunc type is an adapter to allow the use of ordinary +// function as Pet mutator. +type PetFunc func(context.Context, *ent.PetMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PetFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PetMutation", m) + } + return f(ctx, mv) +} + +// The UserFunc type is an adapter to allow the use of ordinary +// function as User mutator. +type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) + } + return f(ctx, mv) +} + +// On executes the given hook only of the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +// +func On(hk ent.Hook, op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +// +func Reject(op ent.Op) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if m.Op().Is(op) { + return nil, fmt.Errorf("%s operation is not allowed", m.Op()) + } + return next.Mutate(ctx, m) + }) + } +} diff --git a/examples/traversal/ent/mutation.go b/examples/traversal/ent/mutation.go new file mode 100644 index 000000000..32833b96a --- /dev/null +++ b/examples/traversal/ent/mutation.go @@ -0,0 +1,1305 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/examples/traversal/ent/group" + "github.com/facebookincubator/ent/examples/traversal/ent/pet" + "github.com/facebookincubator/ent/examples/traversal/ent/user" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeGroup = "Group" + TypePet = "Pet" + TypeUser = "User" +) + +// GroupMutation represents an operation that mutate the Groups +// nodes in the graph. +type GroupMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + users map[int]struct{} + removedusers map[int]struct{} + admin *int + clearedadmin bool +} + +var _ ent.Mutation = (*GroupMutation)(nil) + +// newGroupMutation creates new mutation for $n.Name. +func newGroupMutation(c config, op Op) *GroupMutation { + return &GroupMutation{ + config: c, + op: op, + typ: TypeGroup, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m GroupMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m GroupMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *GroupMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *GroupMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *GroupMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *GroupMutation) ResetName() { + m.name = nil +} + +// AddUserIDs adds the users edge to User by ids. +func (m *GroupMutation) AddUserIDs(ids ...int) { + if m.users == nil { + m.users = make(map[int]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// RemoveUserIDs removes the users edge to User by ids. +func (m *GroupMutation) RemoveUserIDs(ids ...int) { + if m.removedusers == nil { + m.removedusers = make(map[int]struct{}) + } + for i := range ids { + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed ids of users. +func (m *GroupMutation) RemovedUsersIDs() (ids []int) { + for id := range m.removedusers { + ids = append(ids, id) + } + return +} + +// UsersIDs returns the users ids in the mutation. +func (m *GroupMutation) UsersIDs() (ids []int) { + for id := range m.users { + ids = append(ids, id) + } + return +} + +// ResetUsers reset all changes of the users edge. +func (m *GroupMutation) ResetUsers() { + m.users = nil + m.removedusers = nil +} + +// SetAdminID sets the admin edge to User by id. +func (m *GroupMutation) SetAdminID(id int) { + m.admin = &id +} + +// ClearAdmin clears the admin edge to User. +func (m *GroupMutation) ClearAdmin() { + m.clearedadmin = true +} + +// AdminCleared returns if the edge admin was cleared. +func (m *GroupMutation) AdminCleared() bool { + return m.clearedadmin +} + +// AdminID returns the admin id in the mutation. +func (m *GroupMutation) AdminID() (id int, exists bool) { + if m.admin != nil { + return *m.admin, true + } + return +} + +// AdminIDs returns the admin ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// AdminID instead. It exists only for internal usage by the builders. +func (m *GroupMutation) AdminIDs() (ids []int) { + if id := m.admin; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetAdmin reset all changes of the admin edge. +func (m *GroupMutation) ResetAdmin() { + m.admin = nil + m.clearedadmin = false +} + +// Op returns the operation name. +func (m *GroupMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Group). +func (m *GroupMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *GroupMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, group.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *GroupMutation) Field(name string) (ent.Value, bool) { + switch name { + case group.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) SetField(name string, value ent.Value) error { + switch name { + case group.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *GroupMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *GroupMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *GroupMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Group numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *GroupMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *GroupMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *GroupMutation) ClearField(name string) error { + return fmt.Errorf("unknown Group nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *GroupMutation) ResetField(name string) error { + switch name { + case group.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Group field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *GroupMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.users != nil { + edges = append(edges, group.EdgeUsers) + } + if m.admin != nil { + edges = append(edges, group.EdgeAdmin) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *GroupMutation) AddedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) + } + return ids + case group.EdgeAdmin: + if id := m.admin; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *GroupMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedusers != nil { + edges = append(edges, group.EdgeUsers) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *GroupMutation) RemovedIDs(name string) []ent.Value { + switch name { + case group.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *GroupMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedadmin { + edges = append(edges, group.EdgeAdmin) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *GroupMutation) EdgeCleared(name string) bool { + switch name { + case group.EdgeAdmin: + return m.clearedadmin + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *GroupMutation) ClearEdge(name string) error { + switch name { + case group.EdgeAdmin: + m.ClearAdmin() + return nil + } + return fmt.Errorf("unknown Group unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *GroupMutation) ResetEdge(name string) error { + switch name { + case group.EdgeUsers: + m.ResetUsers() + return nil + case group.EdgeAdmin: + m.ResetAdmin() + return nil + } + return fmt.Errorf("unknown Group edge %s", name) +} + +// PetMutation represents an operation that mutate the Pets +// nodes in the graph. +type PetMutation struct { + config + op Op + typ string + id *int + name *string + clearedFields map[string]bool + friends map[int]struct{} + removedfriends map[int]struct{} + owner *int + clearedowner bool +} + +var _ ent.Mutation = (*PetMutation)(nil) + +// newPetMutation creates new mutation for $n.Name. +func newPetMutation(c config, op Op) *PetMutation { + return &PetMutation{ + config: c, + op: op, + typ: TypePet, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PetMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PetMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *PetMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetName sets the name field. +func (m *PetMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *PetMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *PetMutation) ResetName() { + m.name = nil +} + +// AddFriendIDs adds the friends edge to Pet by ids. +func (m *PetMutation) AddFriendIDs(ids ...int) { + if m.friends == nil { + m.friends = make(map[int]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to Pet by ids. +func (m *PetMutation) RemoveFriendIDs(ids ...int) { + if m.removedfriends == nil { + m.removedfriends = make(map[int]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *PetMutation) RemovedFriendsIDs() (ids []int) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *PetMutation) FriendsIDs() (ids []int) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *PetMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// SetOwnerID sets the owner edge to User by id. +func (m *PetMutation) SetOwnerID(id int) { + m.owner = &id +} + +// ClearOwner clears the owner edge to User. +func (m *PetMutation) ClearOwner() { + m.clearedowner = true +} + +// OwnerCleared returns if the edge owner was cleared. +func (m *PetMutation) OwnerCleared() bool { + return m.clearedowner +} + +// OwnerID returns the owner id in the mutation. +func (m *PetMutation) OwnerID() (id int, exists bool) { + if m.owner != nil { + return *m.owner, true + } + return +} + +// OwnerIDs returns the owner ids in the mutation. +// Note that ids always returns len(ids) <= 1 for unique edges, and you should use +// OwnerID instead. It exists only for internal usage by the builders. +func (m *PetMutation) OwnerIDs() (ids []int) { + if id := m.owner; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetOwner reset all changes of the owner edge. +func (m *PetMutation) ResetOwner() { + m.owner = nil + m.clearedowner = false +} + +// Op returns the operation name. +func (m *PetMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Pet). +func (m *PetMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *PetMutation) Fields() []string { + fields := make([]string, 0, 1) + if m.name != nil { + fields = append(fields, pet.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *PetMutation) Field(name string) (ent.Value, bool) { + switch name { + case pet.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) SetField(name string, value ent.Value) error { + switch name { + case pet.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *PetMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *PetMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *PetMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Pet numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *PetMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *PetMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *PetMutation) ClearField(name string) error { + return fmt.Errorf("unknown Pet nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *PetMutation) ResetField(name string) error { + switch name { + case pet.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown Pet field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *PetMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.friends != nil { + edges = append(edges, pet.EdgeFriends) + } + if m.owner != nil { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *PetMutation) AddedIDs(name string) []ent.Value { + switch name { + case pet.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + case pet.EdgeOwner: + if id := m.owner; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *PetMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedfriends != nil { + edges = append(edges, pet.EdgeFriends) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *PetMutation) RemovedIDs(name string) []ent.Value { + switch name { + case pet.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *PetMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedowner { + edges = append(edges, pet.EdgeOwner) + } + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *PetMutation) EdgeCleared(name string) bool { + switch name { + case pet.EdgeOwner: + return m.clearedowner + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *PetMutation) ClearEdge(name string) error { + switch name { + case pet.EdgeOwner: + m.ClearOwner() + return nil + } + return fmt.Errorf("unknown Pet unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *PetMutation) ResetEdge(name string) error { + switch name { + case pet.EdgeFriends: + m.ResetFriends() + return nil + case pet.EdgeOwner: + m.ResetOwner() + return nil + } + return fmt.Errorf("unknown Pet edge %s", name) +} + +// UserMutation represents an operation that mutate the Users +// nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int + age *int + addage *int + name *string + clearedFields map[string]bool + pets map[int]struct{} + removedpets map[int]struct{} + friends map[int]struct{} + removedfriends map[int]struct{} + groups map[int]struct{} + removedgroups map[int]struct{} + manage map[int]struct{} + removedmanage map[int]struct{} +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// newUserMutation creates new mutation for $n.Name. +func newUserMutation(c config, op Op) *UserMutation { + return &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]bool), + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the id value in the mutation. Note that, the id +// is available only if it was provided to the builder. +func (m *UserMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetAge sets the age field. +func (m *UserMutation) SetAge(i int) { + m.age = &i + m.addage = nil +} + +// Age returns the age value in the mutation. +func (m *UserMutation) Age() (r int, exists bool) { + v := m.age + if v == nil { + return + } + return *v, true +} + +// AddAge adds i to age. +func (m *UserMutation) AddAge(i int) { + if m.addage != nil { + *m.addage += i + } else { + m.addage = &i + } +} + +// AddedAge returns the value that was added to the age field in this mutation. +func (m *UserMutation) AddedAge() (r int, exists bool) { + v := m.addage + if v == nil { + return + } + return *v, true +} + +// ResetAge reset all changes of the age field. +func (m *UserMutation) ResetAge() { + m.age = nil + m.addage = nil +} + +// SetName sets the name field. +func (m *UserMutation) SetName(s string) { + m.name = &s +} + +// Name returns the name value in the mutation. +func (m *UserMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// ResetName reset all changes of the name field. +func (m *UserMutation) ResetName() { + m.name = nil +} + +// AddPetIDs adds the pets edge to Pet by ids. +func (m *UserMutation) AddPetIDs(ids ...int) { + if m.pets == nil { + m.pets = make(map[int]struct{}) + } + for i := range ids { + m.pets[ids[i]] = struct{}{} + } +} + +// RemovePetIDs removes the pets edge to Pet by ids. +func (m *UserMutation) RemovePetIDs(ids ...int) { + if m.removedpets == nil { + m.removedpets = make(map[int]struct{}) + } + for i := range ids { + m.removedpets[ids[i]] = struct{}{} + } +} + +// RemovedPets returns the removed ids of pets. +func (m *UserMutation) RemovedPetsIDs() (ids []int) { + for id := range m.removedpets { + ids = append(ids, id) + } + return +} + +// PetsIDs returns the pets ids in the mutation. +func (m *UserMutation) PetsIDs() (ids []int) { + for id := range m.pets { + ids = append(ids, id) + } + return +} + +// ResetPets reset all changes of the pets edge. +func (m *UserMutation) ResetPets() { + m.pets = nil + m.removedpets = nil +} + +// AddFriendIDs adds the friends edge to User by ids. +func (m *UserMutation) AddFriendIDs(ids ...int) { + if m.friends == nil { + m.friends = make(map[int]struct{}) + } + for i := range ids { + m.friends[ids[i]] = struct{}{} + } +} + +// RemoveFriendIDs removes the friends edge to User by ids. +func (m *UserMutation) RemoveFriendIDs(ids ...int) { + if m.removedfriends == nil { + m.removedfriends = make(map[int]struct{}) + } + for i := range ids { + m.removedfriends[ids[i]] = struct{}{} + } +} + +// RemovedFriends returns the removed ids of friends. +func (m *UserMutation) RemovedFriendsIDs() (ids []int) { + for id := range m.removedfriends { + ids = append(ids, id) + } + return +} + +// FriendsIDs returns the friends ids in the mutation. +func (m *UserMutation) FriendsIDs() (ids []int) { + for id := range m.friends { + ids = append(ids, id) + } + return +} + +// ResetFriends reset all changes of the friends edge. +func (m *UserMutation) ResetFriends() { + m.friends = nil + m.removedfriends = nil +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (m *UserMutation) AddGroupIDs(ids ...int) { + if m.groups == nil { + m.groups = make(map[int]struct{}) + } + for i := range ids { + m.groups[ids[i]] = struct{}{} + } +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (m *UserMutation) RemoveGroupIDs(ids ...int) { + if m.removedgroups == nil { + m.removedgroups = make(map[int]struct{}) + } + for i := range ids { + m.removedgroups[ids[i]] = struct{}{} + } +} + +// RemovedGroups returns the removed ids of groups. +func (m *UserMutation) RemovedGroupsIDs() (ids []int) { + for id := range m.removedgroups { + ids = append(ids, id) + } + return +} + +// GroupsIDs returns the groups ids in the mutation. +func (m *UserMutation) GroupsIDs() (ids []int) { + for id := range m.groups { + ids = append(ids, id) + } + return +} + +// ResetGroups reset all changes of the groups edge. +func (m *UserMutation) ResetGroups() { + m.groups = nil + m.removedgroups = nil +} + +// AddManageIDs adds the manage edge to Group by ids. +func (m *UserMutation) AddManageIDs(ids ...int) { + if m.manage == nil { + m.manage = make(map[int]struct{}) + } + for i := range ids { + m.manage[ids[i]] = struct{}{} + } +} + +// RemoveManageIDs removes the manage edge to Group by ids. +func (m *UserMutation) RemoveManageIDs(ids ...int) { + if m.removedmanage == nil { + m.removedmanage = make(map[int]struct{}) + } + for i := range ids { + m.removedmanage[ids[i]] = struct{}{} + } +} + +// RemovedManage returns the removed ids of manage. +func (m *UserMutation) RemovedManageIDs() (ids []int) { + for id := range m.removedmanage { + ids = append(ids, id) + } + return +} + +// ManageIDs returns the manage ids in the mutation. +func (m *UserMutation) ManageIDs() (ids []int) { + for id := range m.manage { + ids = append(ids, id) + } + return +} + +// ResetManage reset all changes of the manage edge. +func (m *UserMutation) ResetManage() { + m.manage = nil + m.removedmanage = nil +} + +// Op returns the operation name. +func (m *UserMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (User). +func (m *UserMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during +// this mutation. Note that, in order to get all numeric +// fields that were in/decremented, call AddedFields(). +func (m *UserMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.age != nil { + fields = append(fields, user.FieldAge) + } + if m.name != nil { + fields = append(fields, user.FieldName) + } + return fields +} + +// Field returns the value of a field with the given name. +// The second boolean value indicates that this field was +// not set, or was not define in the schema. +func (m *UserMutation) Field(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.Age() + case user.FieldName: + return m.Name() + } + return nil, false +} + +// SetField sets the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) SetField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAge(v) + return nil + case user.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedFields returns all numeric fields that were incremented +// or decremented during this mutation. +func (m *UserMutation) AddedFields() []string { + var fields []string + if m.addage != nil { + fields = append(fields, user.FieldAge) + } + return fields +} + +// AddedField returns the numeric value that was in/decremented +// from a field with the given name. The second value indicates +// that this field was not set, or was not define in the schema. +func (m *UserMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case user.FieldAge: + return m.AddedAge() + } + return nil, false +} + +// AddField adds the value for the given name. It returns an +// error if the field is not defined in the schema, or if the +// type mismatch the field type. +func (m *UserMutation) AddField(name string, value ent.Value) error { + switch name { + case user.FieldAge: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAge(v) + return nil + } + return fmt.Errorf("unknown User numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared +// during this mutation. +func (m *UserMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicates if this field was +// cleared in this mutation. +func (m *UserMutation) FieldCleared(name string) bool { + return m.clearedFields[name] +} + +// ClearField clears the value for the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserMutation) ClearField(name string) error { + return fmt.Errorf("unknown User nullable field %s", name) +} + +// ResetField resets all changes in the mutation regarding the +// given field name. It returns an error if the field is not +// defined in the schema. +func (m *UserMutation) ResetField(name string) error { + switch name { + case user.FieldAge: + m.ResetAge() + return nil + case user.FieldName: + m.ResetName() + return nil + } + return fmt.Errorf("unknown User field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this +// mutation. +func (m *UserMutation) AddedEdges() []string { + edges := make([]string, 0, 4) + if m.pets != nil { + edges = append(edges, user.EdgePets) + } + if m.friends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.groups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.manage != nil { + edges = append(edges, user.EdgeManage) + } + return edges +} + +// AddedIDs returns all ids (to other nodes) that were added for +// the given edge name. +func (m *UserMutation) AddedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.pets)) + for id := range m.pets { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.friends)) + for id := range m.friends { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.groups)) + for id := range m.groups { + ids = append(ids, id) + } + return ids + case user.EdgeManage: + ids := make([]ent.Value, 0, len(m.manage)) + for id := range m.manage { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this +// mutation. +func (m *UserMutation) RemovedEdges() []string { + edges := make([]string, 0, 4) + if m.removedpets != nil { + edges = append(edges, user.EdgePets) + } + if m.removedfriends != nil { + edges = append(edges, user.EdgeFriends) + } + if m.removedgroups != nil { + edges = append(edges, user.EdgeGroups) + } + if m.removedmanage != nil { + edges = append(edges, user.EdgeManage) + } + return edges +} + +// RemovedIDs returns all ids (to other nodes) that were removed for +// the given edge name. +func (m *UserMutation) RemovedIDs(name string) []ent.Value { + switch name { + case user.EdgePets: + ids := make([]ent.Value, 0, len(m.removedpets)) + for id := range m.removedpets { + ids = append(ids, id) + } + return ids + case user.EdgeFriends: + ids := make([]ent.Value, 0, len(m.removedfriends)) + for id := range m.removedfriends { + ids = append(ids, id) + } + return ids + case user.EdgeGroups: + ids := make([]ent.Value, 0, len(m.removedgroups)) + for id := range m.removedgroups { + ids = append(ids, id) + } + return ids + case user.EdgeManage: + ids := make([]ent.Value, 0, len(m.removedmanage)) + for id := range m.removedmanage { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this +// mutation. +func (m *UserMutation) ClearedEdges() []string { + edges := make([]string, 0, 4) + return edges +} + +// EdgeCleared returns a boolean indicates if this edge was +// cleared in this mutation. +func (m *UserMutation) EdgeCleared(name string) bool { + switch name { + } + return false +} + +// ClearEdge clears the value for the given name. It returns an +// error if the edge name is not defined in the schema. +func (m *UserMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown User unique edge %s", name) +} + +// ResetEdge resets all changes in the mutation regarding the +// given edge name. It returns an error if the edge is not +// defined in the schema. +func (m *UserMutation) ResetEdge(name string) error { + switch name { + case user.EdgePets: + m.ResetPets() + return nil + case user.EdgeFriends: + m.ResetFriends() + return nil + case user.EdgeGroups: + m.ResetGroups() + return nil + case user.EdgeManage: + m.ResetManage() + return nil + } + return fmt.Errorf("unknown User edge %s", name) +} diff --git a/examples/traversal/ent/pet/pet.go b/examples/traversal/ent/pet/pet.go index 1f3167100..ea221a951 100644 --- a/examples/traversal/ent/pet/pet.go +++ b/examples/traversal/ent/pet/pet.go @@ -10,10 +10,14 @@ const ( // Label holds the string label denoting the pet type in the database. Label = "pet" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // EdgeOwner holds the string denoting the owner edge name in mutations. + EdgeOwner = "owner" + // Table holds the table name of the pet in the database. Table = "pets" // FriendsTable is the table the holds the friends relation/edge. The primary key declared below. diff --git a/examples/traversal/ent/pet_create.go b/examples/traversal/ent/pet_create.go index c950ceeb4..c349ad2fd 100644 --- a/examples/traversal/ent/pet_create.go +++ b/examples/traversal/ent/pet_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/traversal/ent/pet" @@ -19,25 +20,19 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - name *string - friends map[int]struct{} - owner map[int]struct{} + mutation *PetMutation + hooks []Hook } // SetName sets the name field. func (pc *PetCreate) SetName(s string) *PetCreate { - pc.name = &s + pc.mutation.SetName(s) return pc } // AddFriendIDs adds the friends edge to Pet by ids. func (pc *PetCreate) AddFriendIDs(ids ...int) *PetCreate { - if pc.friends == nil { - pc.friends = make(map[int]struct{}) - } - for i := range ids { - pc.friends[ids[i]] = struct{}{} - } + pc.mutation.AddFriendIDs(ids...) return pc } @@ -52,10 +47,7 @@ func (pc *PetCreate) AddFriends(p ...*Pet) *PetCreate { // SetOwnerID sets the owner edge to User by id. func (pc *PetCreate) SetOwnerID(id int) *PetCreate { - if pc.owner == nil { - pc.owner = make(map[int]struct{}) - } - pc.owner[id] = struct{}{} + pc.mutation.SetOwnerID(id) return pc } @@ -74,13 +66,33 @@ func (pc *PetCreate) SetOwner(u *User) *PetCreate { // Save creates the Pet in the database. func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) { - if pc.name == nil { + if _, ok := pc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - if len(pc.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + var ( + err error + node *Pet + ) + if len(pc.hooks) == 0 { + node, err = pc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pc.mutation = mutation + node, err = pc.sqlSave(ctx) + return node, err + }) + for i := len(pc.hooks); i > 0; i-- { + mut = pc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pc.mutation); err != nil { + return nil, err + } } - return pc.sqlSave(ctx) + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -103,15 +115,15 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, } ) - if value := pc.name; value != nil { + if value, ok := pc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) - pe.Name = *value + pe.Name = value } - if nodes := pc.friends; len(nodes) > 0 { + if nodes := pc.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -125,12 +137,12 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := pc.owner; len(nodes) > 0 { + if nodes := pc.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -144,7 +156,7 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/traversal/ent/pet_delete.go b/examples/traversal/ent/pet_delete.go index 02a0641f2..2c4c718e3 100644 --- a/examples/traversal/ent/pet_delete.go +++ b/examples/traversal/ent/pet_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config + hooks []Hook + mutation *PetMutation predicates []predicate.Pet } @@ -30,7 +33,30 @@ func (pd *PetDelete) Where(ps ...predicate.Pet) *PetDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (pd *PetDelete) Exec(ctx context.Context) (int, error) { - return pd.sqlExec(ctx) + var ( + err error + affected int + ) + if len(pd.hooks) == 0 { + affected, err = pd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pd.mutation = mutation + affected, err = pd.sqlExec(ctx) + return affected, err + }) + for i := len(pd.hooks); i > 0; i-- { + mut = pd.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pd.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/traversal/ent/pet_update.go b/examples/traversal/ent/pet_update.go index d311f9db2..ce6e3f20b 100644 --- a/examples/traversal/ent/pet_update.go +++ b/examples/traversal/ent/pet_update.go @@ -8,7 +8,7 @@ package ent import ( "context" - "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,12 +21,9 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - name *string - friends map[int]struct{} - owner map[int]struct{} - removedFriends map[int]struct{} - clearedOwner bool - predicates []predicate.Pet + hooks []Hook + mutation *PetMutation + predicates []predicate.Pet } // Where adds a new predicate for the builder. @@ -37,18 +34,13 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate { // SetName sets the name field. func (pu *PetUpdate) SetName(s string) *PetUpdate { - pu.name = &s + pu.mutation.SetName(s) return pu } // AddFriendIDs adds the friends edge to Pet by ids. func (pu *PetUpdate) AddFriendIDs(ids ...int) *PetUpdate { - if pu.friends == nil { - pu.friends = make(map[int]struct{}) - } - for i := range ids { - pu.friends[ids[i]] = struct{}{} - } + pu.mutation.AddFriendIDs(ids...) return pu } @@ -63,10 +55,7 @@ func (pu *PetUpdate) AddFriends(p ...*Pet) *PetUpdate { // SetOwnerID sets the owner edge to User by id. func (pu *PetUpdate) SetOwnerID(id int) *PetUpdate { - if pu.owner == nil { - pu.owner = make(map[int]struct{}) - } - pu.owner[id] = struct{}{} + pu.mutation.SetOwnerID(id) return pu } @@ -85,12 +74,7 @@ func (pu *PetUpdate) SetOwner(u *User) *PetUpdate { // RemoveFriendIDs removes the friends edge to Pet by ids. func (pu *PetUpdate) RemoveFriendIDs(ids ...int) *PetUpdate { - if pu.removedFriends == nil { - pu.removedFriends = make(map[int]struct{}) - } - for i := range ids { - pu.removedFriends[ids[i]] = struct{}{} - } + pu.mutation.RemoveFriendIDs(ids...) return pu } @@ -105,16 +89,37 @@ func (pu *PetUpdate) RemoveFriends(p ...*Pet) *PetUpdate { // ClearOwner clears the owner edge to User. func (pu *PetUpdate) ClearOwner() *PetUpdate { - pu.clearedOwner = true + pu.mutation.ClearOwner() return pu } // Save executes the query and returns the number of rows/vertices matched by this operation. func (pu *PetUpdate) Save(ctx context.Context) (int, error) { - if len(pu.owner) > 1 { - return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + affected int + ) + if len(pu.hooks) == 0 { + affected, err = pu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + pu.mutation = mutation + affected, err = pu.sqlSave(ctx) + return affected, err + }) + for i := len(pu.hooks); i > 0; i-- { + mut = pu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, pu.mutation); err != nil { + return 0, err + } } - return pu.sqlSave(ctx) + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -157,14 +162,14 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := pu.name; value != nil { + if value, ok := pu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) } - if nodes := pu.removedFriends; len(nodes) > 0 { + if nodes := pu.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -178,12 +183,12 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.friends; len(nodes) > 0 { + if nodes := pu.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -197,12 +202,12 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if pu.clearedOwner { + if pu.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -218,7 +223,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.owner; len(nodes) > 0 { + if nodes := pu.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -232,7 +237,7 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -251,28 +256,19 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - id int - name *string - friends map[int]struct{} - owner map[int]struct{} - removedFriends map[int]struct{} - clearedOwner bool + hooks []Hook + mutation *PetMutation } // SetName sets the name field. func (puo *PetUpdateOne) SetName(s string) *PetUpdateOne { - puo.name = &s + puo.mutation.SetName(s) return puo } // AddFriendIDs adds the friends edge to Pet by ids. func (puo *PetUpdateOne) AddFriendIDs(ids ...int) *PetUpdateOne { - if puo.friends == nil { - puo.friends = make(map[int]struct{}) - } - for i := range ids { - puo.friends[ids[i]] = struct{}{} - } + puo.mutation.AddFriendIDs(ids...) return puo } @@ -287,10 +283,7 @@ func (puo *PetUpdateOne) AddFriends(p ...*Pet) *PetUpdateOne { // SetOwnerID sets the owner edge to User by id. func (puo *PetUpdateOne) SetOwnerID(id int) *PetUpdateOne { - if puo.owner == nil { - puo.owner = make(map[int]struct{}) - } - puo.owner[id] = struct{}{} + puo.mutation.SetOwnerID(id) return puo } @@ -309,12 +302,7 @@ func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne { // RemoveFriendIDs removes the friends edge to Pet by ids. func (puo *PetUpdateOne) RemoveFriendIDs(ids ...int) *PetUpdateOne { - if puo.removedFriends == nil { - puo.removedFriends = make(map[int]struct{}) - } - for i := range ids { - puo.removedFriends[ids[i]] = struct{}{} - } + puo.mutation.RemoveFriendIDs(ids...) return puo } @@ -329,16 +317,37 @@ func (puo *PetUpdateOne) RemoveFriends(p ...*Pet) *PetUpdateOne { // ClearOwner clears the owner edge to User. func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne { - puo.clearedOwner = true + puo.mutation.ClearOwner() return puo } // Save executes the query and returns the updated entity. func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) { - if len(puo.owner) > 1 { - return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"") + + var ( + err error + node *Pet + ) + if len(puo.hooks) == 0 { + node, err = puo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PetMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + puo.mutation = mutation + node, err = puo.sqlSave(ctx) + return node, err + }) + for i := len(puo.hooks); i > 0; i-- { + mut = puo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, puo.mutation); err != nil { + return nil, err + } } - return puo.sqlSave(ctx) + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -369,20 +378,24 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { Table: pet.Table, Columns: pet.Columns, ID: &sqlgraph.FieldSpec{ - Value: puo.id, Type: field.TypeInt, Column: pet.FieldID, }, }, } - if value := puo.name; value != nil { + id, ok := puo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing Pet.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := puo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: pet.FieldName, }) } - if nodes := puo.removedFriends; len(nodes) > 0 { + if nodes := puo.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -396,12 +409,12 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.friends; len(nodes) > 0 { + if nodes := puo.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -415,12 +428,12 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if puo.clearedOwner { + if puo.mutation.OwnerCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -436,7 +449,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.owner; len(nodes) > 0 { + if nodes := puo.mutation.OwnerIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, Inverse: true, @@ -450,7 +463,7 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/examples/traversal/ent/privacy/privacy.go b/examples/traversal/ent/privacy/privacy.go new file mode 100644 index 000000000..967185bd9 --- /dev/null +++ b/examples/traversal/ent/privacy/privacy.go @@ -0,0 +1,219 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package privacy + +import ( + "context" + "errors" + "fmt" + + "github.com/facebookincubator/ent/examples/traversal/ent" +) + +var ( + // Allow may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an allow decision. + Allow = errors.New("ent/privacy: allow rule") + + // Deny may be returned by read/write rules to indicate that the policy + // evaluation should terminate with an deny decision. + Deny = errors.New("ent/privacy: deny rule") + + // Skip may be returned by read/write rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = errors.New("ent/privacy: skip rule") +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +type ( + // ReadPolicy combines multiple read rules into a single policy. + ReadPolicy []ReadRule + + // ReadRule defines the interface deciding whether a read is allowed. + ReadRule interface { + EvalRead(context.Context, ent.Value) error + } +) + +// EvalRead evaluates a load against a read policy. +func (policy ReadPolicy) EvalRead(ctx context.Context, v ent.Value) error { + for _, rule := range policy { + switch err := rule.EvalRead(ctx, v); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// ReadRuleFunc type is an adapter to allow the use of +// ordinary functions as read rules. +type ReadRuleFunc func(context.Context, ent.Value) error + +// Eval calls f(ctx, v). +func (f ReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + return f(ctx, v) +} + +type ( + // WritePolicy combines multiple write rules into a single policy. + WritePolicy []WriteRule + + // WriteRule defines the interface deciding whether a write is allowed. + WriteRule interface { + EvalWrite(context.Context, ent.Mutation) error + } +) + +// EvalWrite evaluates a mutation against a write policy. +func (policy WritePolicy) EvalWrite(ctx context.Context, m ent.Mutation) error { + for _, rule := range policy { + switch err := rule.EvalWrite(ctx, m); { + case err == nil || errors.Is(err, Skip): + case errors.Is(err, Allow): + return nil + default: + return err + } + } + return nil +} + +// WriteRuleFunc type is an adapter to allow the use of +// ordinary functions as write rules. +type WriteRuleFunc func(context.Context, ent.Mutation) error + +// Eval calls f(ctx, m). +func (f WriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// Policy groups read and write policies. +type Policy struct { + Read ReadPolicy + Write WritePolicy +} + +// EvalRead forwards evaluation to read policy. +func (policy Policy) EvalRead(ctx context.Context, v ent.Value) error { + return policy.Read.EvalRead(ctx, v) +} + +// EvalWrite forwards evaluation to write policy. +func (policy Policy) EvalWrite(ctx context.Context, m ent.Mutation) error { + return policy.Write.EvalWrite(ctx, m) +} + +// ReadWriteRule is the interface that groups read and write rules. +type ReadWriteRule interface { + ReadRule + WriteRule +} + +// AlwaysAllowRule returns a read/write rule that returns an allow decision. +func AlwaysAllowRule() ReadWriteRule { + return fixedDecisionRule{Allow} +} + +// AlwaysDenyRule returns a read/write rule that returns a deny decision. +func AlwaysDenyRule() ReadWriteRule { + return fixedDecisionRule{Deny} +} + +type fixedDecisionRule struct{ err error } + +func (f fixedDecisionRule) EvalRead(context.Context, ent.Value) error { return f.err } +func (f fixedDecisionRule) EvalWrite(context.Context, ent.Mutation) error { return f.err } + +// The GroupReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type GroupReadRuleFunc func(context.Context, *ent.Group) error + +// EvalRead calls f(ctx, v). +func (f GroupReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Group); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Group", v) +} + +// The GroupWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type GroupWriteRuleFunc func(context.Context, *ent.GroupMutation) error + +// EvalWrite calls f(ctx, m). +func (f GroupWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.GroupMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.GroupMutation", m) +} + +// The PetReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type PetReadRuleFunc func(context.Context, *ent.Pet) error + +// EvalRead calls f(ctx, v). +func (f PetReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.Pet); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.Pet", v) +} + +// The PetWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type PetWriteRuleFunc func(context.Context, *ent.PetMutation) error + +// EvalWrite calls f(ctx, m). +func (f PetWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.PetMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.PetMutation", m) +} + +// The UserReadRuleFunc type is an adapter to allow the use of ordinary +// functions as a read rule. +type UserReadRuleFunc func(context.Context, *ent.User) error + +// EvalRead calls f(ctx, v). +func (f UserReadRuleFunc) EvalRead(ctx context.Context, v ent.Value) error { + if v, ok := v.(*ent.User); ok { + return f(ctx, v) + } + return Denyf("ent/privacy: unexpected value type %T, expect *ent.User", v) +} + +// The UserWriteRuleFunc type is an adapter to allow the use of ordinary +// functions as a write rule. +type UserWriteRuleFunc func(context.Context, *ent.UserMutation) error + +// EvalWrite calls f(ctx, m). +func (f UserWriteRuleFunc) EvalWrite(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.UserMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.UserMutation", m) +} diff --git a/examples/traversal/ent/runtime.go b/examples/traversal/ent/runtime.go new file mode 100644 index 000000000..250581550 --- /dev/null +++ b/examples/traversal/ent/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// The init function reads all schema descriptors with runtime +// code (default values, validators or hooks) and stitches it +// to their package variables. +func init() { +} diff --git a/examples/traversal/ent/runtime/runtime.go b/examples/traversal/ent/runtime/runtime.go new file mode 100644 index 000000000..62efa7095 --- /dev/null +++ b/examples/traversal/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in github.com/facebookincubator/ent/examples/traversal/ent/runtime.go + +const ( + Version = "(devel)" // Version of ent codegen. +) diff --git a/examples/traversal/ent/tx.go b/examples/traversal/ent/tx.go index 00b4ad30d..52cc9304d 100644 --- a/examples/traversal/ent/tx.go +++ b/examples/traversal/ent/tx.go @@ -10,7 +10,6 @@ import ( "context" "github.com/facebookincubator/ent/dialect" - "github.com/facebookincubator/ent/examples/traversal/ent/migrate" ) // Tx is a transactional client that is created by calling Client.Tx(). @@ -36,13 +35,15 @@ func (tx *Tx) Rollback() error { // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { - return &Client{ - config: tx.config, - Schema: migrate.NewSchema(tx.driver), - Group: NewGroupClient(tx.config), - Pet: NewPetClient(tx.config), - User: NewUserClient(tx.config), - } + client := &Client{config: tx.config} + client.init() + return client +} + +func (tx *Tx) init() { + tx.Group = NewGroupClient(tx.config) + tx.Pet = NewPetClient(tx.config) + tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. diff --git a/examples/traversal/ent/user/user.go b/examples/traversal/ent/user/user.go index 4706f8a4e..7c01b9f04 100644 --- a/examples/traversal/ent/user/user.go +++ b/examples/traversal/ent/user/user.go @@ -10,12 +10,19 @@ const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldAge holds the string denoting the age vertex property in the database. - FieldAge = "age" - // FieldName holds the string denoting the name vertex property in the database. + FieldID = "id" // FieldAge holds the string denoting the age vertex property in the database. + FieldAge = "age" // FieldName holds the string denoting the name vertex property in the database. FieldName = "name" + // EdgePets holds the string denoting the pets edge name in mutations. + EdgePets = "pets" + // EdgeFriends holds the string denoting the friends edge name in mutations. + EdgeFriends = "friends" + // EdgeGroups holds the string denoting the groups edge name in mutations. + EdgeGroups = "groups" + // EdgeManage holds the string denoting the manage edge name in mutations. + EdgeManage = "manage" + // Table holds the table name of the user in the database. Table = "users" // PetsTable is the table the holds the pets relation/edge. diff --git a/examples/traversal/ent/user_create.go b/examples/traversal/ent/user_create.go index 2f3599ee3..1924f74ec 100644 --- a/examples/traversal/ent/user_create.go +++ b/examples/traversal/ent/user_create.go @@ -9,6 +9,7 @@ package ent import ( "context" "errors" + "fmt" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" "github.com/facebookincubator/ent/examples/traversal/ent/group" @@ -20,34 +21,25 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - age *int - name *string - pets map[int]struct{} - friends map[int]struct{} - groups map[int]struct{} - manage map[int]struct{} + mutation *UserMutation + hooks []Hook } // SetAge sets the age field. func (uc *UserCreate) SetAge(i int) *UserCreate { - uc.age = &i + uc.mutation.SetAge(i) return uc } // SetName sets the name field. func (uc *UserCreate) SetName(s string) *UserCreate { - uc.name = &s + uc.mutation.SetName(s) return uc } // AddPetIDs adds the pets edge to Pet by ids. func (uc *UserCreate) AddPetIDs(ids ...int) *UserCreate { - if uc.pets == nil { - uc.pets = make(map[int]struct{}) - } - for i := range ids { - uc.pets[ids[i]] = struct{}{} - } + uc.mutation.AddPetIDs(ids...) return uc } @@ -62,12 +54,7 @@ func (uc *UserCreate) AddPets(p ...*Pet) *UserCreate { // AddFriendIDs adds the friends edge to User by ids. func (uc *UserCreate) AddFriendIDs(ids ...int) *UserCreate { - if uc.friends == nil { - uc.friends = make(map[int]struct{}) - } - for i := range ids { - uc.friends[ids[i]] = struct{}{} - } + uc.mutation.AddFriendIDs(ids...) return uc } @@ -82,12 +69,7 @@ func (uc *UserCreate) AddFriends(u ...*User) *UserCreate { // AddGroupIDs adds the groups edge to Group by ids. func (uc *UserCreate) AddGroupIDs(ids ...int) *UserCreate { - if uc.groups == nil { - uc.groups = make(map[int]struct{}) - } - for i := range ids { - uc.groups[ids[i]] = struct{}{} - } + uc.mutation.AddGroupIDs(ids...) return uc } @@ -102,12 +84,7 @@ func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { // AddManageIDs adds the manage edge to Group by ids. func (uc *UserCreate) AddManageIDs(ids ...int) *UserCreate { - if uc.manage == nil { - uc.manage = make(map[int]struct{}) - } - for i := range ids { - uc.manage[ids[i]] = struct{}{} - } + uc.mutation.AddManageIDs(ids...) return uc } @@ -122,13 +99,36 @@ func (uc *UserCreate) AddManage(g ...*Group) *UserCreate { // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if uc.age == nil { + if _, ok := uc.mutation.Age(); !ok { return nil, errors.New("ent: missing required field \"age\"") } - if uc.name == nil { + if _, ok := uc.mutation.Name(); !ok { return nil, errors.New("ent: missing required field \"name\"") } - return uc.sqlSave(ctx) + var ( + err error + node *User + ) + if len(uc.hooks) == 0 { + node, err = uc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uc.mutation = mutation + node, err = uc.sqlSave(ctx) + return node, err + }) + for i := len(uc.hooks); i > 0; i-- { + mut = uc.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uc.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX calls Save and panics if Save returns an error. @@ -151,23 +151,23 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, } ) - if value := uc.age; value != nil { + if value, ok := uc.mutation.Age(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) - u.Age = *value + u.Age = value } - if value := uc.name; value != nil { + if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) - u.Name = *value + u.Name = value } - if nodes := uc.pets; len(nodes) > 0 { + if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -181,12 +181,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.friends; len(nodes) > 0 { + if nodes := uc.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -200,12 +200,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.groups; len(nodes) > 0 { + if nodes := uc.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -219,12 +219,12 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) } - if nodes := uc.manage; len(nodes) > 0 { + if nodes := uc.mutation.ManageIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -238,7 +238,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges = append(_spec.Edges, edge) diff --git a/examples/traversal/ent/user_delete.go b/examples/traversal/ent/user_delete.go index 02cc3560f..13e1176d3 100644 --- a/examples/traversal/ent/user_delete.go +++ b/examples/traversal/ent/user_delete.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -19,6 +20,8 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config + hooks []Hook + mutation *UserMutation predicates []predicate.User } @@ -30,7 +33,30 @@ func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return ud.sqlExec(ctx) + var ( + err error + affected int + ) + if len(ud.hooks) == 0 { + affected, err = ud.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + ud.mutation = mutation + affected, err = ud.sqlExec(ctx) + return affected, err + }) + for i := len(ud.hooks); i > 0; i-- { + mut = ud.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, ud.mutation); err != nil { + return 0, err + } + } + return affected, err } // ExecX is like Exec, but panics if an error occurs. diff --git a/examples/traversal/ent/user_update.go b/examples/traversal/ent/user_update.go index d9a20ddaa..981fba757 100644 --- a/examples/traversal/ent/user_update.go +++ b/examples/traversal/ent/user_update.go @@ -8,6 +8,7 @@ package ent import ( "context" + "fmt" "github.com/facebookincubator/ent/dialect/sql" "github.com/facebookincubator/ent/dialect/sql/sqlgraph" @@ -21,18 +22,9 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - age *int - addage *int - name *string - pets map[int]struct{} - friends map[int]struct{} - groups map[int]struct{} - manage map[int]struct{} - removedPets map[int]struct{} - removedFriends map[int]struct{} - removedGroups map[int]struct{} - removedManage map[int]struct{} - predicates []predicate.User + hooks []Hook + mutation *UserMutation + predicates []predicate.User } // Where adds a new predicate for the builder. @@ -43,35 +35,26 @@ func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { // SetAge sets the age field. func (uu *UserUpdate) SetAge(i int) *UserUpdate { - uu.age = &i - uu.addage = nil + uu.mutation.ResetAge() + uu.mutation.SetAge(i) return uu } // AddAge adds i to age. func (uu *UserUpdate) AddAge(i int) *UserUpdate { - if uu.addage == nil { - uu.addage = &i - } else { - *uu.addage += i - } + uu.mutation.AddAge(i) return uu } // SetName sets the name field. func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.name = &s + uu.mutation.SetName(s) return uu } // AddPetIDs adds the pets edge to Pet by ids. func (uu *UserUpdate) AddPetIDs(ids ...int) *UserUpdate { - if uu.pets == nil { - uu.pets = make(map[int]struct{}) - } - for i := range ids { - uu.pets[ids[i]] = struct{}{} - } + uu.mutation.AddPetIDs(ids...) return uu } @@ -86,12 +69,7 @@ func (uu *UserUpdate) AddPets(p ...*Pet) *UserUpdate { // AddFriendIDs adds the friends edge to User by ids. func (uu *UserUpdate) AddFriendIDs(ids ...int) *UserUpdate { - if uu.friends == nil { - uu.friends = make(map[int]struct{}) - } - for i := range ids { - uu.friends[ids[i]] = struct{}{} - } + uu.mutation.AddFriendIDs(ids...) return uu } @@ -106,12 +84,7 @@ func (uu *UserUpdate) AddFriends(u ...*User) *UserUpdate { // AddGroupIDs adds the groups edge to Group by ids. func (uu *UserUpdate) AddGroupIDs(ids ...int) *UserUpdate { - if uu.groups == nil { - uu.groups = make(map[int]struct{}) - } - for i := range ids { - uu.groups[ids[i]] = struct{}{} - } + uu.mutation.AddGroupIDs(ids...) return uu } @@ -126,12 +99,7 @@ func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { // AddManageIDs adds the manage edge to Group by ids. func (uu *UserUpdate) AddManageIDs(ids ...int) *UserUpdate { - if uu.manage == nil { - uu.manage = make(map[int]struct{}) - } - for i := range ids { - uu.manage[ids[i]] = struct{}{} - } + uu.mutation.AddManageIDs(ids...) return uu } @@ -146,12 +114,7 @@ func (uu *UserUpdate) AddManage(g ...*Group) *UserUpdate { // RemovePetIDs removes the pets edge to Pet by ids. func (uu *UserUpdate) RemovePetIDs(ids ...int) *UserUpdate { - if uu.removedPets == nil { - uu.removedPets = make(map[int]struct{}) - } - for i := range ids { - uu.removedPets[ids[i]] = struct{}{} - } + uu.mutation.RemovePetIDs(ids...) return uu } @@ -166,12 +129,7 @@ func (uu *UserUpdate) RemovePets(p ...*Pet) *UserUpdate { // RemoveFriendIDs removes the friends edge to User by ids. func (uu *UserUpdate) RemoveFriendIDs(ids ...int) *UserUpdate { - if uu.removedFriends == nil { - uu.removedFriends = make(map[int]struct{}) - } - for i := range ids { - uu.removedFriends[ids[i]] = struct{}{} - } + uu.mutation.RemoveFriendIDs(ids...) return uu } @@ -186,12 +144,7 @@ func (uu *UserUpdate) RemoveFriends(u ...*User) *UserUpdate { // RemoveGroupIDs removes the groups edge to Group by ids. func (uu *UserUpdate) RemoveGroupIDs(ids ...int) *UserUpdate { - if uu.removedGroups == nil { - uu.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uu.removedGroups[ids[i]] = struct{}{} - } + uu.mutation.RemoveGroupIDs(ids...) return uu } @@ -206,12 +159,7 @@ func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { // RemoveManageIDs removes the manage edge to Group by ids. func (uu *UserUpdate) RemoveManageIDs(ids ...int) *UserUpdate { - if uu.removedManage == nil { - uu.removedManage = make(map[int]struct{}) - } - for i := range ids { - uu.removedManage[ids[i]] = struct{}{} - } + uu.mutation.RemoveManageIDs(ids...) return uu } @@ -226,7 +174,31 @@ func (uu *UserUpdate) RemoveManage(g ...*Group) *UserUpdate { // Save executes the query and returns the number of rows/vertices matched by this operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return uu.sqlSave(ctx) + + var ( + err error + affected int + ) + if len(uu.hooks) == 0 { + affected, err = uu.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uu.mutation = mutation + affected, err = uu.sqlSave(ctx) + return affected, err + }) + for i := len(uu.hooks); i > 0; i-- { + mut = uu.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uu.mutation); err != nil { + return 0, err + } + } + return affected, err } // SaveX is like Save, but panics if an error occurs. @@ -269,28 +241,28 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } - if value := uu.age; value != nil { + if value, ok := uu.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.addage; value != nil { + if value, ok := uu.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uu.name; value != nil { + if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uu.removedPets; len(nodes) > 0 { + if nodes := uu.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -304,12 +276,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.pets; len(nodes) > 0 { + if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -323,12 +295,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedFriends; len(nodes) > 0 { + if nodes := uu.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -342,12 +314,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.friends; len(nodes) > 0 { + if nodes := uu.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -361,12 +333,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedGroups; len(nodes) > 0 { + if nodes := uu.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -380,12 +352,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.groups; len(nodes) > 0 { + if nodes := uu.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -399,12 +371,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uu.removedManage; len(nodes) > 0 { + if nodes := uu.mutation.RemovedManageIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -418,12 +390,12 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uu.manage; len(nodes) > 0 { + if nodes := uu.mutation.ManageIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -437,7 +409,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) @@ -456,51 +428,32 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - id int - age *int - addage *int - name *string - pets map[int]struct{} - friends map[int]struct{} - groups map[int]struct{} - manage map[int]struct{} - removedPets map[int]struct{} - removedFriends map[int]struct{} - removedGroups map[int]struct{} - removedManage map[int]struct{} + hooks []Hook + mutation *UserMutation } // SetAge sets the age field. func (uuo *UserUpdateOne) SetAge(i int) *UserUpdateOne { - uuo.age = &i - uuo.addage = nil + uuo.mutation.ResetAge() + uuo.mutation.SetAge(i) return uuo } // AddAge adds i to age. func (uuo *UserUpdateOne) AddAge(i int) *UserUpdateOne { - if uuo.addage == nil { - uuo.addage = &i - } else { - *uuo.addage += i - } + uuo.mutation.AddAge(i) return uuo } // SetName sets the name field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.name = &s + uuo.mutation.SetName(s) return uuo } // AddPetIDs adds the pets edge to Pet by ids. func (uuo *UserUpdateOne) AddPetIDs(ids ...int) *UserUpdateOne { - if uuo.pets == nil { - uuo.pets = make(map[int]struct{}) - } - for i := range ids { - uuo.pets[ids[i]] = struct{}{} - } + uuo.mutation.AddPetIDs(ids...) return uuo } @@ -515,12 +468,7 @@ func (uuo *UserUpdateOne) AddPets(p ...*Pet) *UserUpdateOne { // AddFriendIDs adds the friends edge to User by ids. func (uuo *UserUpdateOne) AddFriendIDs(ids ...int) *UserUpdateOne { - if uuo.friends == nil { - uuo.friends = make(map[int]struct{}) - } - for i := range ids { - uuo.friends[ids[i]] = struct{}{} - } + uuo.mutation.AddFriendIDs(ids...) return uuo } @@ -535,12 +483,7 @@ func (uuo *UserUpdateOne) AddFriends(u ...*User) *UserUpdateOne { // AddGroupIDs adds the groups edge to Group by ids. func (uuo *UserUpdateOne) AddGroupIDs(ids ...int) *UserUpdateOne { - if uuo.groups == nil { - uuo.groups = make(map[int]struct{}) - } - for i := range ids { - uuo.groups[ids[i]] = struct{}{} - } + uuo.mutation.AddGroupIDs(ids...) return uuo } @@ -555,12 +498,7 @@ func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { // AddManageIDs adds the manage edge to Group by ids. func (uuo *UserUpdateOne) AddManageIDs(ids ...int) *UserUpdateOne { - if uuo.manage == nil { - uuo.manage = make(map[int]struct{}) - } - for i := range ids { - uuo.manage[ids[i]] = struct{}{} - } + uuo.mutation.AddManageIDs(ids...) return uuo } @@ -575,12 +513,7 @@ func (uuo *UserUpdateOne) AddManage(g ...*Group) *UserUpdateOne { // RemovePetIDs removes the pets edge to Pet by ids. func (uuo *UserUpdateOne) RemovePetIDs(ids ...int) *UserUpdateOne { - if uuo.removedPets == nil { - uuo.removedPets = make(map[int]struct{}) - } - for i := range ids { - uuo.removedPets[ids[i]] = struct{}{} - } + uuo.mutation.RemovePetIDs(ids...) return uuo } @@ -595,12 +528,7 @@ func (uuo *UserUpdateOne) RemovePets(p ...*Pet) *UserUpdateOne { // RemoveFriendIDs removes the friends edge to User by ids. func (uuo *UserUpdateOne) RemoveFriendIDs(ids ...int) *UserUpdateOne { - if uuo.removedFriends == nil { - uuo.removedFriends = make(map[int]struct{}) - } - for i := range ids { - uuo.removedFriends[ids[i]] = struct{}{} - } + uuo.mutation.RemoveFriendIDs(ids...) return uuo } @@ -615,12 +543,7 @@ func (uuo *UserUpdateOne) RemoveFriends(u ...*User) *UserUpdateOne { // RemoveGroupIDs removes the groups edge to Group by ids. func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...int) *UserUpdateOne { - if uuo.removedGroups == nil { - uuo.removedGroups = make(map[int]struct{}) - } - for i := range ids { - uuo.removedGroups[ids[i]] = struct{}{} - } + uuo.mutation.RemoveGroupIDs(ids...) return uuo } @@ -635,12 +558,7 @@ func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { // RemoveManageIDs removes the manage edge to Group by ids. func (uuo *UserUpdateOne) RemoveManageIDs(ids ...int) *UserUpdateOne { - if uuo.removedManage == nil { - uuo.removedManage = make(map[int]struct{}) - } - for i := range ids { - uuo.removedManage[ids[i]] = struct{}{} - } + uuo.mutation.RemoveManageIDs(ids...) return uuo } @@ -655,7 +573,31 @@ func (uuo *UserUpdateOne) RemoveManage(g ...*Group) *UserUpdateOne { // Save executes the query and returns the updated entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return uuo.sqlSave(ctx) + + var ( + err error + node *User + ) + if len(uuo.hooks) == 0 { + node, err = uuo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + uuo.mutation = mutation + node, err = uuo.sqlSave(ctx) + return node, err + }) + for i := len(uuo.hooks); i > 0; i-- { + mut = uuo.hooks[i-1](mut) + } + if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { + return nil, err + } + } + return node, err } // SaveX is like Save, but panics if an error occurs. @@ -686,34 +628,38 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ - Value: uuo.id, Type: field.TypeInt, Column: user.FieldID, }, }, } - if value := uuo.age; value != nil { + id, ok := uuo.mutation.ID() + if !ok { + return nil, fmt.Errorf("missing User.ID for update") + } + _spec.Node.ID.Value = id + if value, ok := uuo.mutation.Age(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.addage; value != nil { + if value, ok := uuo.mutation.AddedAge(); ok { _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ Type: field.TypeInt, - Value: *value, + Value: value, Column: user.FieldAge, }) } - if value := uuo.name; value != nil { + if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, - Value: *value, + Value: value, Column: user.FieldName, }) } - if nodes := uuo.removedPets; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedPetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -727,12 +673,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.pets; len(nodes) > 0 { + if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: false, @@ -746,12 +692,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedFriends; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedFriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -765,12 +711,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.friends; len(nodes) > 0 { + if nodes := uuo.mutation.FriendsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, @@ -784,12 +730,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedGroups; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedGroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -803,12 +749,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.groups; len(nodes) > 0 { + if nodes := uuo.mutation.GroupsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: true, @@ -822,12 +768,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - if nodes := uuo.removedManage; len(nodes) > 0 { + if nodes := uuo.mutation.RemovedManageIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -841,12 +787,12 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := uuo.manage; len(nodes) > 0 { + if nodes := uuo.mutation.ManageIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, Inverse: true, @@ -860,7 +806,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { }, }, } - for k, _ := range nodes { + for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } _spec.Edges.Add = append(_spec.Edges.Add, edge) diff --git a/go.mod b/go.mod index 01cda225c..b7f7cb1e4 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,8 @@ require ( github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.4.0 go.opencensus.io v0.22.0 + golang.org/x/mod v0.2.0 // indirect golang.org/x/sync v0.0.0-20190423024810-112230192c58 - golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a - golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 + golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 ) diff --git a/go.sum b/go.sum index 60341ef46..c816b10d9 100644 --- a/go.sum +++ b/go.sum @@ -62,15 +62,21 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -81,6 +87,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEha golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -91,8 +98,15 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a h1:TwMENskLwU2NnWBzrJGEWHqSiGUkO/B4rfyhwqDxDYQ= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd h1:hHkvGJK23seRCflePJnVa9IMv8fsuavSCWKd11kDQFs= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=