content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.datastax.oss.driver.examples.mapper.killrvideo.user;
  
  import com.datastax.oss.driver.api.mapper.annotations.Dao;
  import com.datastax.oss.driver.api.mapper.annotations.QueryProvider;
  import com.datastax.oss.driver.api.mapper.annotations.Select;
  import java.util.Optional;
  import java.util.UUID;
  
  @Dao
  public interface UserDao {
  
    /** Simple selection by full primary key. */
    @Select
    User get(UUID userid);
  
    @Select
    UserCredentials getCredentials(String email);
  
    /**
     * An alternative to query providers is default methods that call other methods on the DAO.
     *
     * <p>The only drawback is that those other methods have to be part of the DAO's public API.
     */
    default User getByEmail(String email) {
      UserCredentials credentials = getCredentials(email);
      return (credentials == null) ? null : get(credentials.getUserid());
    }
  
    /**
     * Creating a user is more than a single insert: we have to update two different tables, check
     * that the email is not used already, and handle password encryption.
     *
     * <p>We use a query provider to wrap everything into a single method.
     *
     * <p>Note that you could opt for a more layered approach: only expose basic operations on the DAO
     * (insertCredentialsIfNotExists, insertUser...) and add a service layer on top for more complex
     * logic. Both designs are valid, this is a matter of personal choice.
     *
     * @return {@code true} if the new user was created, or {@code false} if this email address was
     *     already taken.
     */
    @QueryProvider(
        providerClass = CreateUserQueryProvider.class,
        entityHelpers = {User.class, UserCredentials.class})
    boolean create(User user, char[] password);
  
    /**
     * Similar to {@link #create}, this encapsulates encryption so we use a query provider.
     *
     * @return the authenticated user, or {@link Optional#empty()} if the credentials are invalid.
     */
    @QueryProvider(
        providerClass = LoginQueryProvider.class,
        entityHelpers = {User.class, UserCredentials.class})
    Optional<User> login(String email, char[] password);
  }
  