Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Luca Guadagnini
    @tryIO
    but it would be better
    because you mix commands with queries
    you should separate them
    you have to identify your views/projections that are the results of your queries and call them in a proper way
    I don't know if you got the idea
    Luca Guadagnini
    @tryIO
    (sorry I have to go)
    vivek poddar
    @vivekimsit
    np, but yes I would need more clarification
    goqp
    @goqp
    @tryio > beyond that prototyping is a non-issue, the real problem here is object-definition-consistency, to many ways to do it
    Goods point. That is a bigger issue.

    @try io > and pay attention about prototyping, it's not easy to extend an object, unfortunatly it's much worst than you think:

    oh I agree remember? I said its complicated and confusing. But the nut cases that developed prototyping for SELF thought that it would be an easier alternative to classes, they said so.

    Paulo
    @ptrecenti
    @goqp somebody can help me to understand how can I use horizontal decorator to filter data from database?
    public interface People {
    
        Iterable<Person> iterate();
    
        Person add(Email email);
    
    }
    goqp
    @goqp
    @ptrecenti you don't want to use a horizontal decorator, you want to use a vertical decorator following Yegors paradigm.
    goqp
    @goqp
    It would look like: new filteredPeopleB ( new filteredPeopleA ( new peopleSet ("//databasetarget") ) );
    Paulo
    @ptrecenti
    something like that
    public final class PgPersonByEmail implements People {
    
        private final DataSource dataSource;
        private final People source;
        private final Email email;
    
        public PgPersonByEmail(DataSource dataSource, Email email) {
            this(
                    dataSource,
                    new PgPeople(dataSource),
                    email
            );
        }
    
        public PgPersonByEmail(DataSource dataSource, People source, Email email) {
            this.dataSource = dataSource;
            this.source = source;
            this.email = email;
        }
    
        public Person first() {
            return iterate().iterator().next();
        }
    
        @Override
        public Iterable<Person> iterate() {
            try {
                return new JdbcSession(this.dataSource)
                        .sql("SELECT id FROM person where email = ?")
                        .set(email.toString()).select(
                                new ListOutcome<>(
                                        (ListOutcome.Mapping<Person>) rset -> new PgPerson(
                                                dataSource,
                                                rset.getInt(1)
    
                                        )
                                )
                        );
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public Person add(Email email) {
            return this.source.add(email);
        }
    }
    goqp
    @goqp
    Hmmm...Im not fully familiar with functional aspects in Java yet, but I think you missed some braces no?
    goqp
    @goqp
    Oh I see, it's a cast.
    goqp
    @goqp
    Okay, I am still kind of confused because I dont know jcabi and the lambda mapping part is new to me, BUT, this looks wrong.
    You are doing all of the work all over again in this decorator.
    First, you need a target or origin result set representing the list of people that is unfiltered. This is the only object that will EVER touch the database. So is that what you are trying to show here, and then you will decorate?
    Maybe I didnt know how to read this actually...
    Paulo
    @ptrecenti
    yes that is the point, the original implementation I'm selecting all database, but I don't want to fetch all database and to get only one record
    goqp
    @goqp
    oh so, like if the person has ID whatever, or email whatever, you only want to go to the database and get that one record.
    rather than getting the entire list of people.
    yes?
    Paulo
    @ptrecenti
    yes
    this is the original implementation
    public final class PgPeople implements People {
    
        private final DataSource dataSource;
    
        public PgPeople(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        @Override
        public Iterable<Person> iterate() {
            try {
                return new JdbcSession(this.dataSource)
                        .sql("SELECT id FROM person")
                        .select(
                                new ListOutcome<>(
                                        (ListOutcome.Mapping<Person>) rset -> new PgPerson(
                                                dataSource,
                                                rset.getInt(1)
                                        )
                                )
                        );
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public Person add(Email email) {
            try {
                return new PgPerson(
                        this.dataSource,
                        new JdbcSession(dataSource)
                                .sql("INSERT INTO person (email) VALUES (?)")
                                .set(email.toString())
                                .update(new SingleOutcome<>(Long.class)).intValue()
                );
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
    }
    goqp
    @goqp
    Okay, here's your problem. It's conceptual.
    A list of people is all people who fit some criteria. By definition if no criteria are specified then that means the entire set.
    A filtered list of people is a list of people, who, having all people who fit a criteria, only returns you some subset that matches an additional criteria. That is why he is a decorator.
    You cant mix and match the ideas like I think you are doing.
    Paulo
    @ptrecenti
    so should I have to apply something like a filter inside of PgPeople right?
    ok now I see
    goqp
    @goqp
    Once you have the list, you have to stick with him. If you want to filter over him you have to do it to the entire list.
    You cant try to inject some kind of new sql to make the inner list act differently from what he was doing before.
    That would be a procedural idea.
    Paulo
    @ptrecenti
    something like that
    public final class PgOrganizations implements Organizations {
    
        private final DataSource dataSource;
        private final Filter filteredBy;
        private final Object[] params;
    
        public PgOrganizations(DataSource dataSource) {
            this(
                    dataSource,
                    Filter.NONE
            );
        }
    
        public PgOrganizations(DataSource dataSource, Filter filteredBy, Object... params) {
            this.dataSource = dataSource;
            this.filteredBy = filteredBy;
            this.params = params;
        }
    
        @Override
        public Iterable<Organization> iterate() {
            try {
    
                final JdbcSession session = new JdbcSession(this.dataSource);
    
                session.sql(
                        String.format("SELECT id FROM organization %s", filteredBy.where)
                );
    
                for (Object param : params) {
                    session.set(param);
                }
    
                return session.select(
                        new ListOutcome<>(
                                (ListOutcome.Mapping<Organization>) rset -> new PgOrganization(
                                        dataSource,
                                        rset.getInt(1)
                                )
                        )
                );
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public Organization add(OrganizationUrl url) {
            try {
                return new PgOrganization(
                        this.dataSource,
                        new JdbcSession(dataSource)
                                .sql("INSERT INTO organization (email) VALUES (?)")
                                .set(url.toString())
                                .update(new SingleOutcome<>(Long.class)).intValue()
                );
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
        public enum Filter {
            NONE(""),
            BY_URL("where url = ?");
    
            private final String where;
    
            Filter(String where) {
                this.where = where;
            }
        }
    }
    goqp
    @goqp
    no this is going in the wrong direction
    you are creating a super object that is god-controlling all of the needed behavior in this problem.
    think about modelling
    Paulo
    @ptrecenti
    do you have any example about what do I need to re-think?
    goqp
    @goqp
    I will try and write one. Lets think about the problem space of a bit. Why do you need a list of people who only have a single email or is restricted?
    What is going on here that we are MODELLING?
    Paulo
    @ptrecenti
    I got your point
    the problem that I'm trying to solve is sometimes I need to find a person by email but the identity of the person is an int id like that
    @EqualsAndHashCode(of = "id")
    public final class PgPerson implements Person {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(PgPerson.class);
    
        private final DataSource dataSource;
        private final int id;
        private final Account account;
    
        public PgPerson(DataSource dataSource, int id) {
            this(
                    dataSource,
                    id,
                    new PgAccount(
                            dataSource,
                            id
                    )
            );
        }
    
        public PgPerson(DataSource dataSource, int id, Account account) {
            this.dataSource = dataSource;
            this.id = id;
            this.account = account;
        }
    
        @Override
        public int id() {
            return this.id;
        }
    
    
        @Override
        public void update(Name name) {
    
            LOGGER.debug(
                    "name: {}",
                    name.toString());
    
            try {
                new JdbcSession(this.dataSource)
                        .sql("update person set first=?, middle=?, last=? where id = ?")
                        .set(name.first())
                        .set(name.middle())
                        .set(name.last())
                        .set(this.id)
                        .execute();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public Name name() {
            try {
                return new JdbcSession(this.dataSource)
                        .sql("select COALESCE(first,''), COALESCE(middle,''), COALESCE(last,'') from person where id = ?")
                        .set(this.id)
                        .select((Outcome<Name>) (rset, stmt) -> {
                            rset.next();
                            return new DefaultName(
                                    rset.getString(1),
                                    rset.getString(2),
                                    rset.getString(3)
                            );
                        });
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public Account account() {
            return this.account;
        }
    
    }
    goqp
    @goqp
    right, could be actually we want to find a person by first name, last name, or combination of both of them too.
    Could be by organization.
    The list of attributes is pretty large.
    Paulo
    @ptrecenti
    in the case of email it's unique and could define the identity of the person, but not the name (first, last, soon) because many people can have the same last name and this will return to me a list of people
    but I really don't know how fit the requirement to filter by last name (for example) without do what I made in the people class to filter by last name without rewrite the iterate method or use filter like the organizations
    goqp
    @goqp
    what I am saying is finding a person by email is a special case of finding some subset of people by any criteria
    whats the difference? None.