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

Make quarkus-renarde compatible with panache reactive #250

Open
ITrium-Salah opened this issue Sep 20, 2024 · 3 comments
Open

Make quarkus-renarde compatible with panache reactive #250

ITrium-Salah opened this issue Sep 20, 2024 · 3 comments

Comments

@ITrium-Salah
Copy link

Quarkus-Renarde is a nice project and the backoffice feature can help me a lot!
However it seem that the framework is not compatible with panache reactive (hibernate reactive) and it is frustrating to not be able to use this extension in my services (15...20 services) without switching to a non reactive orm paradigm.

Any chances to see this project compatible with hibernate reactive?

Thanks for your works on this project!

@FroMage
Copy link
Contributor

FroMage commented Sep 23, 2024

We never made it compatible with Hibernate Reactive because nobody ever asked.

I'm not sure I'll have time to add support for it right now, but I can help you if you feel like trying to make a PR for it.

@ITrium-Salah
Copy link
Author

I'm not against to give it a try, but my knowledge of extension and specifically the gizmo code generator is very low (zero :-) ).

If you can give me an example to convert this method:

private void editOrCreateView(MethodCreator m, String controllerClass, String entityClass, String simpleName,
            List<ModelField> fields, Mode mode) {
        if (mode == Mode.EDIT) {
            m.getParameterAnnotations(0).addAnnotation(RestPath.class).addValue("value", "id");
            m.addAnnotation(Path.class).addValue("value", "edit/{id}");
        } else {
            m.addAnnotation(Path.class).addValue("value", "create");
        }
        m.addAnnotation(GET.class);
        m.addAnnotation(Transactional.class);
        m.addAnnotation(Produces.class).addValue("value", new String[] { MediaType.TEXT_HTML });

        ResultHandle instance = getTemplateInstance(m,
                URI_PREFIX_NO_SLASH + "/" + simpleName + "/" + (mode == Mode.CREATE ? "create" : "edit"));
        AssignableResultHandle entityVariable = null;
        if (mode == Mode.EDIT) {
            entityVariable = findEntityById(m, controllerClass, entityClass);

            instance = m.invokeInterfaceMethod(
                    MethodDescriptor.ofMethod(TemplateInstance.class, "data", TemplateInstance.class, String.class,
                            Object.class),
                    instance, m.load("entity"), entityVariable);
        }

        for (ModelField field : fields) {
            ResultHandle data = null;
            if (field.type == ModelField.Type.Relation
                    || field.type == ModelField.Type.MultiRelation
                    || field.type == ModelField.Type.MultiMultiRelation) {
                ResultHandle list = m
                        .invokeStaticMethod(MethodDescriptor.ofMethod(field.relationClass, "listAll", List.class));
                data = m.invokeStaticMethod(
                        MethodDescriptor.ofMethod(BackUtil.class, "entityPossibleValues", Map.class, List.class), list);
            } else if (field.type == ModelField.Type.Enum) {
                ResultHandle list = m
                        .invokeStaticMethod(
                                MethodDescriptor.ofMethod(field.getClassName(), "values",
                                        "[" + field.entityField.descriptor));
                data = m.invokeStaticMethod(
                        MethodDescriptor.ofMethod(BackUtil.class, "enumPossibleValues", Map.class, Enum[].class), list);
            }
            if (data != null) {
                instance = m.invokeInterfaceMethod(
                        MethodDescriptor.ofMethod(TemplateInstance.class, "data", TemplateInstance.class, String.class,
                                Object.class),
                        instance, m.load(field.name + "PossibleValues"), data);
            }
            if (mode == Mode.EDIT
                    && (field.type == ModelField.Type.MultiRelation || field.type == ModelField.Type.MultiMultiRelation)) {
                // instance.data("relationCurrentValues", BackUtil.entityCurrentValues(entity.getRelation()))
                ResultHandle relation = m.invokeVirtualMethod(
                        MethodDescriptor.ofMethod(entityClass, field.entityField.getGetterName(),
                                field.entityField.descriptor),
                        entityVariable);
                data = m.invokeStaticMethod(
                        MethodDescriptor.ofMethod(BackUtil.class, "entityCurrentValues", List.class, List.class), relation);
                instance = m.invokeInterfaceMethod(
                        MethodDescriptor.ofMethod(TemplateInstance.class, "data", TemplateInstance.class, String.class,
                                Object.class),
                        instance, m.load(field.name + "CurrentValues"), data);
            }
            if (mode == Mode.EDIT
                    && field.type == ModelField.Type.Binary
                    && field.entityField.descriptor.equals("Ljava/sql/Blob;")) {
                // if(entity.blob != null) instance.data("blobLength", entity.blob.length()))
                ResultHandle blob = m.invokeVirtualMethod(
                        MethodDescriptor.ofMethod(entityClass, field.entityField.getGetterName(),
                                field.entityField.descriptor),
                        entityVariable);
                BranchResult ifBranch = m.ifNotNull(blob);
                try (BytecodeCreator trueBranch = ifBranch.trueBranch()) {
                    // call length to preload it
                    ResultHandle blob2 = trueBranch.invokeVirtualMethod(
                            MethodDescriptor.ofMethod(entityClass, field.entityField.getGetterName(),
                                    field.entityField.descriptor),
                            entityVariable);
                    data = trueBranch.invokeInterfaceMethod(MethodDescriptor.ofMethod(Blob.class, "length", long.class), blob2);
                    trueBranch.invokeInterfaceMethod(
                            MethodDescriptor.ofMethod(TemplateInstance.class, "data", TemplateInstance.class, String.class,
                                    Object.class),
                            instance, trueBranch.load(field.name + "Length"), data);
                }
                ifBranch.falseBranch().close();
            }
        }
        m.returnValue(instance);
    }

Into

private void editOrCreateViewReactive(MethodCreator m, String controllerClass, String entityClass, String simpleName,
            List<ModelField> fields, Mode mode){
...
}

With some focuses on how to manipulate the gizmo api to use lambda to write things like Entity.listAll().chain(lambda).map(lambda). ...

@FroMage
Copy link
Contributor

FroMage commented Oct 1, 2024

Ah, yes, indeed it's more complex than this. Give me a bit of time to get back to you, sorry.

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