Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array of Enums produce incomplete/empty code #108

Closed
pepie opened this issue Dec 12, 2024 · 7 comments
Closed

Array of Enums produce incomplete/empty code #108

pepie opened this issue Dec 12, 2024 · 7 comments

Comments

@pepie
Copy link

pepie commented Dec 12, 2024

Hello,

Thank you for this package, it is very helpful.

Supadart will produce invalid/incomplete code statements for tables with array of Enums. It seems to be unable to map the collection of enum values.

The code works as expected with an array of Strings (varchar) but fails for Enums. I suspect it might work fine for other primitive types, but I did not check.

Example:

Suppose we have an Enum for user groups defined as

CREATE TYPE public.usergroup AS ENUM ('USERS', 'ADMIN', 'MODERATOR');

we define a Profile table with a column that holds a list of group names:

create table
  public.profiles (
    id uuid not null default extensions.uuid_generate_v4 (),
    ...
 user_groups usergroup[] not null default '{{USERS}}'::usergroup[],
    ...

  ) tablespace pg_default;

This will generate a class for Profile with the following code snippet

if (userGroups != null) 'user_groups':       ,    

notice the empty space between the semicolon and the comma - a missing expression for the column values. This code is incomplete and will break the app.

The code work as expected when user_groups is array of varchar:

create table
  public.profiles (
    id uuid not null default extensions.uuid_generate_v4 (),
    ...
user_groups character varying[] not null default '{''USERS''}'::character varying[]

  ) tablespace pg_default;

will produce (as expected):

if (userGroups != null) 'user_groups' : userGroups.map((e) => e).toList() ,

I've attached two screenshots for more context.

Screenshot 2024-12-12 at 4 59 11 AM Screenshot 2024-12-12 at 4 56 25 AM
@mmvergara
Copy link
Owner

Thanks for opening an issue!,

I see, this might be a missing feature, i did not see. will work and update on it.

btw, in case you missed i replied to the last i ssue you made #107 thanks again

@pepie
Copy link
Author

pepie commented Dec 12, 2024

Thanks for opening an issue!,

I see, this might be a missing feature, i did not see. will work and update on it.

btw, in case you missed i replied to the last i ssue you made #107 thanks again

Thank you!

@mmvergara
Copy link
Owner

@pepie as of #110 1.6.6 the issue should now be fixed, please update your cli then try generating... i would appreciate your feedback, thankss

@pepie
Copy link
Author

pepie commented Dec 12, 2024

I just tested it and noticed a few breaking changes.

Here are my steps (in sequence) and findings:

context:

  1. I updated the package with dart pub global activate supadart

_If there is an update/upgrade cli command then please add it to the document (unless I missed).

I then run "supadart" to generate the classes.

Issues

  1. I get config file not found after the upgrade
    running supadart returns "config file not found" even though the config file was still present (supadart.yaml).

Error:
Config file not found. ... Please provide the url and key for your Supabase project...
**Notes:

[ ] supadart.yaml already existed (same directory) from the previous configuration
[] I reran `supadart --init` and was prompted to overwrite or keep the existing config file.  I chose to overwrite the existing config. ]

I noticed the new config had the following changes:
a. Case changed for SP property key names:
supabase_url ==> SUPABASE_URL supabase_anon_key ==> SUPABASE_ANON_KEY
This might be why the new version is unable to read the SB url and key values.

It would be nice to be able to use environment variables here, to prevent having to type the long anon key everytime my model is changed.
Something like
```
 SUPABASE_URL: ${SUPABASE_URL}
```
 or fallback to reading the environment vars when the URL or ANON key is not provided. So, values in the config would take precedence over environment vars or vice-versa.
  1. When separated: false is used, running supadart creates a single file (lib/models/generated_classess.dart) which does not import lib/models/supadart_header.dart. The enum values are declared in supadart_header, so all enums referenced in generated_classes.dart will fail.

  2. All enums must now be explicitly declared/mapped in the config. This seems like a regression since the previous library discovered them automatically. This also makes it more error prone as modifications are made to the model/enums.

enums:
   mood: [happy, sad, neutral, excited, angry]

Note: I have specific mappings from my table, which means I now have to map all tables, enums, and possibly views. I'm not sure if this is intended.

  1. The original problem still exists
    I am still seeing missing map values for the list of enums.
    I've included some screenshots and the relevant schemas to help with testing:
create table
  public.profiles (
    id uuid not null default extensions.uuid_generate_v4 (),
    first_name character varying(100) null,
    last_name character varying(100) null,
    user_groups usergroup[] not null default '{{USERS}}'::usergroup[],
  ) tablespace pg_default;
  
  CREATE TYPE public.usergroup AS ENUM ('USERS', 'ADMIN', 'MODERATOR');

and my config


enums:
  usergroups: [USERS, ADMINS, GUESTS]

output: lib/models/
separated: true
dart: false

mappings:
  profiles: profile

# Optional, used to exclude methods from generated classes
exclude:
  # - toJson
  # - copyWith

One last note:
In the model that fails, the fromJson() method is calling dynamic.from() for the column in question. The .from() is undefined - see the attached screen.

Both dynamic.from() and dynamic.values() are reported as undefined.
Maybe an extension is missing.

Here's the relevant line from the generated code.

userGroups: jsonn['user_groups'] != null ? dynamic.from(jsonn['user_groups'].map((e) => dynamic.values.byName(e.toString())).toList()) : [],
Screenshot 2024-12-12 at 11 43 57 AM Screenshot 2024-12-12 at 11 34 54 AM Screenshot 2024-12-12 at 1 11 33 PM

@mmvergara
Copy link
Owner

mmvergara commented Dec 12, 2024

@pepie thanks for replying

All enums must now be explicitly declared/mapped in the config. This seems like a regression since the previous library discovered them automatically. This also makes it more error prone as modifications are made to the model/enums.

we are limited by what the swagger api can offer, the reason for this is that if you have created an enum,

"properties": {
        "id": {
          "default": "gen_random_uuid()",
          "description": "Note:\nThis is a Primary Key.\u003Cpk/\u003E",
          "format": "uuid",
          "type": "string"
        },
        "col_mood": {
          "enum": [
            "happy",
            "sad",
            "neutral",
            "excited",
            "angry"
          ],
          "format": "public.mood",
          "type": "string"
        },
        "col_mood_array": {
          "format": "public.mood[]",
          "items": {
            "type": "string"
          },
          // NO ENUM PROPERTY HERE
          "type": "array"
        }
      },
      "type": "object"
    }

Notice that we don't get the enum property here, so if we don't specify it we can't access it. this actually the reason on why it did nothing on your end.

It's fine if the user doesn't use the enum type as an enum[] type, we it can deal with that but if the user has it, it can't generate unless specified.

i should probably add it to docs that you don't need to specify the enums if you are not using them as enum[]

Supadart Header

About the supadart_header that file is only generated when doing separted:true, it likely did not reference the enum type because it failed to generate it in the generated_classes.dart should be fixed now


Please try upgrading the cli and generating again.
Im sorry for the bad updates, just been a bit out of it lately.

@pepie
Copy link
Author

pepie commented Dec 12, 2024

No worries. I'm sure you have a million more urgent things to get to. I appreciate your effort.

The limitations you described make sense.
I'll upgrade and try again

@pepie
Copy link
Author

pepie commented Dec 12, 2024

v 1.6.7 looks good @mmvergara

I can confirm the enum values are generated properly in both separated and single file mode (separated:false).
Thank you!

I plan to implement the insert functions tonight and will likely create a few views.
I'll let you know if I find anything.

Thank you, again, for your work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants