private Map<String, Attachment> readInlineImages(final long htmlContentId) {
    QBinaryContent qBinaryContent = QBinaryContent.binaryContent;
    QInlineImage qInlineImage = QInlineImage.inlineImage;
    List<Tuple> inlineImageTuples =
        querydslSupport.execute(
            (connection, configuration) -> {
              return new SQLQuery(connection, configuration)
                  .from(qInlineImage)
                  .leftJoin(qBinaryContent)
                  .on(qBinaryContent.binaryContentId.eq(qInlineImage.binaryContentId))
                  .where(qInlineImage.htmlContentId.eq(htmlContentId))
                  .orderBy(qInlineImage.index_.asc())
                  .list(
                      qBinaryContent.blobId,
                      qBinaryContent.contentType_,
                      qBinaryContent.name_,
                      qInlineImage.cid_);
            });

    Map<String, Attachment> inlineImageByCidMap = new LinkedHashMap<>();
    for (Tuple inlineImageTuple : inlineImageTuples) {
      String contentType = inlineImageTuple.get(qBinaryContent.contentType_);
      String name = inlineImageTuple.get(qBinaryContent.name_);
      Long blobId = inlineImageTuple.get(qBinaryContent.blobId);
      Attachment attachment = createAttachment(blobId, contentType, name);

      inlineImageByCidMap.put(inlineImageTuple.get(qInlineImage.cid_), attachment);
    }
    return inlineImageByCidMap;
  }
  private Collection<Attachment> readAttachments(final long storedEmailId) {
    QAttachment qAttachment = QAttachment.attachment;
    QBinaryContent qBinaryContent = QBinaryContent.binaryContent;
    List<Tuple> attachmentTuples =
        querydslSupport.execute(
            (connection, configuration) -> {
              return new SQLQuery(connection, configuration)
                  .from(qAttachment)
                  .join(qBinaryContent)
                  .on(qAttachment.binaryContentId.eq(qBinaryContent.binaryContentId))
                  .where(qAttachment.storedEmailId.eq(storedEmailId))
                  .orderBy(qAttachment.index_.asc())
                  .list(qBinaryContent.blobId, qBinaryContent.contentType_, qBinaryContent.name_);
            });

    Collection<Attachment> attachments = new ArrayList<>();
    for (Tuple attachmentTuple : attachmentTuples) {
      String contentType = attachmentTuple.get(qBinaryContent.contentType_);
      String name = attachmentTuple.get(qBinaryContent.name_);
      Long blobId = attachmentTuple.get(qBinaryContent.blobId);
      Attachment attachment = createAttachment(blobId, contentType, name);

      attachments.add(attachment);
    }
    return attachments;
  }
  private HtmlContent readHtmlContent(final long storedEmailId) {
    QHtmlContent qHtmlContent = QHtmlContent.htmlContent;
    Tuple htmlContentTuple =
        querydslSupport.execute(
            (connection, configuration) -> {
              return new SQLQuery(connection, configuration)
                  .from(qHtmlContent)
                  .where(qHtmlContent.storedEmailId.eq(storedEmailId))
                  .uniqueResult(qHtmlContent.blobId, qHtmlContent.htmlContentId);
            });

    if (htmlContentTuple == null) {
      return null;
    }

    HtmlContent htmlContent = new HtmlContent();
    byte[] htmlContentBytes = readBlob(htmlContentTuple.get(qHtmlContent.blobId));
    if (htmlContentBytes.length > 0) {
      htmlContent.withHtml(new String(htmlContentBytes, StandardCharsets.UTF_8));
    }
    Map<String, Attachment> inlineImageByCidMap =
        readInlineImages(htmlContentTuple.get(qHtmlContent.htmlContentId));
    if (!inlineImageByCidMap.isEmpty()) {
      htmlContent.withInlineImageByCidMap(inlineImageByCidMap);
    }
    return htmlContent;
  }
  private void deleteTextContent(final long storedEmailId) {
    QTextContent qTextContent = QTextContent.textContent;
    Tuple tuple =
        querydslSupport.execute(
            (connection, configuration) -> {
              return new SQLQuery(connection, configuration)
                  .from(qTextContent)
                  .where(qTextContent.storedEmailId.eq(storedEmailId))
                  .uniqueResult(qTextContent.textContentId, qTextContent.blobId);
            });

    if (tuple == null) {
      return;
    }

    Long textContentId = tuple.get(qTextContent.textContentId);
    querydslSupport.execute(
        (connection, configuration) -> {
          return new SQLDeleteClause(connection, configuration, qTextContent)
              .where(qTextContent.textContentId.eq(textContentId))
              .execute();
        });

    deleteBlob(tuple.get(qTextContent.blobId));
  }
  @Test
  public void ScalarQueries() {
    BooleanExpression filter = product.name.startsWith("A");

    // count
    assertEquals(10l, sql().from(product).where(filter).count());

    // countDistinct
    assertEquals(10l, sql().from(product).where(filter).distinct().count());

    // list
    assertEquals(10, sql().from(product).where(filter).list(product.name).size());

    // list with limit
    assertEquals(3, sql().from(product).limit(3).list(product.name).size());

    // list with offset
    //        assertEquals(7, sql().from(product).offset(3).list(product.name).size());

    // list with limit and offset
    assertEquals(3, sql().from(product).offset(3).limit(3).list(product.name).size());

    // list multiple
    for (Tuple row : sql().from(product).list(product.productId, product.name, product.amount)) {
      assertNotNull(row.get(0, Object.class));
      assertNotNull(row.get(1, Object.class));
      assertNotNull(row.get(2, Object.class));
    }

    // listResults
    SearchResults<String> results = sql().from(product).limit(3).listResults(product.name);
    assertEquals(3, results.getResults().size());
    assertEquals(30l, results.getTotal());
  }
  public static Info fromTuple(Tuple tuple) {
    Integer id = tuple.get(QBalance.balance.id);
    if (id == null) return null;

    String name = DatabaseManager.getInstance().getPlayerName(id);
    Long amount = tuple.get(QBalance.balance.amount);

    Info info = new Info();
    info.setName(name);
    info.setAmount(amount == null ? 0 : amount);
    return info;
  }
    @Override
    protected LineItem map(Tuple tuple) {
      LineItem lineItem = new LineItem();

      lineItem.setOrderId(tuple.get(qLineItem.orderid));
      lineItem.setLineNumber(tuple.get(qLineItem.linenum));
      lineItem.setItemId(tuple.get(qLineItem.itemid));
      lineItem.setQuantity(tuple.get(qLineItem.quantity));
      lineItem.setUnitPrice(tuple.get(qLineItem.unitprice).doubleValue());

      return lineItem;
    }
    private void addIssueKey(@Nonnull PullRequest pullRequest, @Nonnull final Tuple tuple) {
      final String issueKey = tuple.get(issueMapping.ISSUE_KEY);

      if (!pullRequest.getIssueKeys().contains(issueKey)) {
        pullRequest.getIssueKeys().add(issueKey);
      }
    }
    private void addParticipant(@Nonnull PullRequest pullRequest, @Nonnull final Tuple tuple) {
      final String username = tuple.get(participantMapping.USERNAME);
      final Boolean approved = tuple.get(participantMapping.APPROVED);
      final String role = tuple.get(participantMapping.ROLE);

      // We are left joining so only include the participant if it is available
      if (username != null || approved != null || role != null) {
        Participant participant =
            new Participant(username, approved == null ? false : approved, role);

        if (pullRequest.getParticipants() == null) {
          pullRequest.setParticipants(new ArrayList<Participant>());
        }

        if (!pullRequest.getParticipants().contains(participant)) {
          pullRequest.getParticipants().add(participant);
        }
      }
    }
  @Override
  public Email read(final long storedEmailId) {
    return transactionPropagator.required(
        () -> {
          QEmail qEmail = QEmail.email;
          Tuple emailTuple =
              querydslSupport.execute(
                  (connection, configuration) -> {
                    return new SQLQuery(connection, configuration)
                        .from(qEmail)
                        .where(qEmail.storedEmailId.eq(storedEmailId))
                        .uniqueResult(qEmail.subject_, qEmail.storedEmailId);
                  });

          if (emailTuple == null) {
            return null;
          }

          Email email = new Email().withSubject(emailTuple.get(qEmail.subject_));

          email.withTextContent(readTextContent(storedEmailId));

          HtmlContent htmlContent = readHtmlContent(storedEmailId);
          email = email.withHtmlContent(htmlContent);

          Collection<Attachment> attachments = readAttachments(storedEmailId);
          email = email.withAttachments(attachments);

          EmailAddress from = readFrom(storedEmailId);
          email = email.withFrom(from);

          Recipients recipients = readRecipients(storedEmailId);
          email.withRecipients(recipients);

          return email;
        });
  }
  public List<Cliente> getClientes(String sortParameter, int start, int limit, String userUID) {
    List<Tuple> compras = clientesDAO.getClientes(sortParameter, start, limit, userUID);

    List<Cliente> clientes = new ArrayList<Cliente>();
    for (Tuple compra : compras) {
      Cliente cliente = new Cliente();
      cliente.setId(compra.get(0, Long.class));
      cliente.setNombre(compra.get(1, String.class));
      cliente.setApellidos(compra.get(2, String.class));
      cliente.setDireccion(compra.get(3, String.class));
      cliente.setPoblacion(compra.get(4, String.class));
      cliente.setCp(compra.get(5, String.class));
      cliente.setProvincia(compra.get(6, String.class));
      cliente.setTelefono(compra.get(7, String.class));
      cliente.setEmail(compra.get(8, String.class));
      clientes.add(cliente);
    }

    return clientes;
  }
    @Override
    protected Order map(Tuple tuple) {
      Order order = new Order();

      order.setBillAddress1(tuple.get(qOrders.billaddr1));
      order.setBillAddress2(tuple.get(qOrders.billaddr2));
      order.setBillCity(tuple.get(qOrders.billcity));
      order.setBillCountry(tuple.get(qOrders.billcountry));
      order.setBillState(tuple.get(qOrders.billstate));
      order.setBillToFirstName(tuple.get(qOrders.billtofirstname));
      order.setBillToLastName(tuple.get(qOrders.billtolastname));
      order.setBillZip(tuple.get(qOrders.billzip));
      order.setShipAddress1(tuple.get(qOrders.shipaddr1));
      order.setShipAddress2(tuple.get(qOrders.shipaddr2));
      order.setShipCity(tuple.get(qOrders.shipcity));
      order.setShipCountry(tuple.get(qOrders.shipcountry));
      order.setShipState(tuple.get(qOrders.shipstate));
      order.setShipToFirstName(tuple.get(qOrders.shiptofirstname));
      order.setShipToLastName(tuple.get(qOrders.shiptolastname));
      order.setShipZip(tuple.get(qOrders.shipzip));
      order.setCardType(tuple.get(qOrders.cardtype));
      order.setCourier(tuple.get(qOrders.courier));
      order.setCreditCard(tuple.get(qOrders.creditcard));
      order.setExpiryDate(tuple.get(qOrders.exprdate));
      order.setLocale(tuple.get(qOrders.locale));
      order.setOrderDate(tuple.get(qOrders.orderdate));
      order.setOrderId(tuple.get(qOrders.orderid));
      order.setTotalPrice(tuple.get(qOrders.totalprice).doubleValue());
      order.setUsername(tuple.get(qOrders.userid));
      order.setStatus(tuple.get(qOrderStatus.status));

      return order;
    }
    @Nonnull
    private PullRequest buildPullRequest(
        @Nonnull final Integer pullRequestId, @Nonnull final Tuple tuple) {
      PullRequest pullRequest = new PullRequest(pullRequestId);

      final Long remoteId = tuple.get(prMapping.REMOTE_ID);
      pullRequest.setRemoteId(remoteId == null ? -1 : remoteId);
      final Integer repositoryId = tuple.get(prMapping.TO_REPOSITORY_ID);
      pullRequest.setRepositoryId(repositoryId == null ? -1 : repositoryId);
      pullRequest.setName(tuple.get(prMapping.NAME));
      pullRequest.setUrl(tuple.get(prMapping.URL));
      final String lastStatus = tuple.get(prMapping.LAST_STATUS);
      if (lastStatus != null) {
        pullRequest.setStatus(PullRequestStatus.fromRepositoryPullRequestMapping(lastStatus));
      }
      pullRequest.setCreatedOn(tuple.get(prMapping.CREATED_ON));
      pullRequest.setUpdatedOn(tuple.get(prMapping.UPDATED_ON));
      pullRequest.setAuthor(tuple.get(prMapping.AUTHOR));
      final Integer commentCount = tuple.get(prMapping.COMMENT_COUNT);
      pullRequest.setCommentCount(commentCount == null ? 0 : commentCount);
      pullRequest.setExecutedBy(tuple.get(prMapping.EXECUTED_BY));

      String sourceBranch = tuple.get(prMapping.SOURCE_BRANCH);
      String sourceRepo = tuple.get(prMapping.SOURCE_REPO);
      String orgHostUrl = tuple.get(orgMapping.HOST_URL);

      pullRequest.setSource(
          new PullRequestRef(
              sourceBranch,
              sourceRepo,
              PullRequestTransformer.createRepositoryUrl(orgHostUrl, sourceRepo)));

      String destinationBranch = tuple.get(prMapping.DESTINATION_BRANCH);
      String orgName = tuple.get(orgMapping.NAME);
      String slug = tuple.get(repositoryMapping.SLUG);

      String repositoryLabel = PullRequestTransformer.createRepositoryLabel(orgName, slug);
      String repositoryUrl = RepositoryTransformer.createRepositoryUrl(orgHostUrl, orgName, slug);

      pullRequest.setDestination(
          new PullRequestRef(destinationBranch, repositoryLabel, repositoryUrl));

      return pullRequest;
    }