public ExchangeRate getDailyExchangeRateFromDate(CurrencyPair currencyPair, long timestamp)
      throws CantGetExchangeRateException {
    DatabaseTable table =
        this.database.getTable(
            BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TABLE_NAME);

    table.addStringFilter(
        BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_FROM_CURRENCY_COLUMN_NAME,
        currencyPair.getFrom().getCode(),
        DatabaseFilterType.EQUAL);
    table.addStringFilter(
        BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TO_CURRENCY_COLUMN_NAME,
        currencyPair.getTo().getCode(),
        DatabaseFilterType.EQUAL);
    table.addStringFilter(
        BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TIMESTAMP_COLUMN_NAME,
        String.valueOf(timestamp),
        DatabaseFilterType.EQUAL);

    try {
      table.loadToMemory();
      List<DatabaseTableRecord> records = table.getRecords();
      if (records.size() > 0) {
        DatabaseTableRecord record = records.get(0);
        return constructExchangeRateFromRecord(record);
      } else {
        throw new CantGetExchangeRateException(
            CantGetExchangeRateException.DEFAULT_MESSAGE,
            null,
            "Failed to get daily exchange rate for timestamp: " + timestamp,
            "Exchange Rate not found in database");
      }

    } catch (CantLoadTableToMemoryException e) {
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          "Failed to get daily exchange rate for timestamp: " + timestamp,
          "Couldn't load table to memory");
    } catch (CantCreateExchangeRateException e) {
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          "Failed to get daily exchange rate for timestamp: " + timestamp,
          "Couldn't create ExchangeRate object");
    }
  }
  public void updateDailyExchangeRateTable(
      CurrencyPair currencyPair, List<ExchangeRate> exchangeRates)
      throws CantSaveExchangeRateException {
    List<String> exchangeRateTimestampsInDatabase = new ArrayList<>();

    DatabaseTable table =
        this.database.getTable(
            BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TABLE_NAME);
    table.addStringFilter(
        BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_FROM_CURRENCY_COLUMN_NAME,
        currencyPair.getFrom().getCode(),
        DatabaseFilterType.EQUAL);
    table.addStringFilter(
        BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TO_CURRENCY_COLUMN_NAME,
        currencyPair.getTo().getCode(),
        DatabaseFilterType.EQUAL);

    try {
      table.loadToMemory();

      for (DatabaseTableRecord record : table.getRecords()) {
        String timestamp =
            record.getStringValue(
                BitcoinVenezuelaProviderDatabaseConstants
                    .DAILY_EXCHANGE_RATES_TIMESTAMP_COLUMN_NAME);
        exchangeRateTimestampsInDatabase.add(timestamp);
      }
    } catch (CantLoadTableToMemoryException e) {
      throw new CantSaveExchangeRateException(
          CantSaveExchangeRateException.DEFAULT_MESSAGE,
          e,
          "Failed to get ExchangeRates in database for CurrencyPair: " + currencyPair.toString(),
          "Couldn't load table to memory");
    }

    for (ExchangeRate e : exchangeRates) {
      String currentTimestamp = String.valueOf(e.getTimestamp());
      if (!exchangeRateTimestampsInDatabase.contains(currentTimestamp)) {
        this.saveDailyExchangeRate(e); // TODO: improve this.. saving one by one..
      }
    }
  }
  public List<ExchangeRate> getQueriedExchangeRateHistory(
      ExchangeRateType exchangeRateType, CurrencyPair currencyPair)
      throws CantGetExchangeRateException {
    List<ExchangeRate> exchangeRateList = new ArrayList<>();
    DatabaseTable table = null;

    switch (exchangeRateType) {
      case CURRENT:
        table =
            this.database.getTable(
                BitcoinVenezuelaProviderDatabaseConstants.CURRENT_EXCHANGE_RATES_TABLE_NAME);
        table.addStringFilter(
            BitcoinVenezuelaProviderDatabaseConstants
                .CURRENT_EXCHANGE_RATES_FROM_CURRENCY_COLUMN_NAME,
            currencyPair.getFrom().getCode(),
            DatabaseFilterType.EQUAL);
        table.addStringFilter(
            BitcoinVenezuelaProviderDatabaseConstants
                .CURRENT_EXCHANGE_RATES_TO_CURRENCY_COLUMN_NAME,
            currencyPair.getTo().getCode(),
            DatabaseFilterType.EQUAL);
        break;
      case DAILY:
        table =
            this.database.getTable(
                BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TABLE_NAME);
        table.addStringFilter(
            BitcoinVenezuelaProviderDatabaseConstants
                .DAILY_EXCHANGE_RATES_FROM_CURRENCY_COLUMN_NAME,
            currencyPair.getFrom().getCode(),
            DatabaseFilterType.EQUAL);
        table.addStringFilter(
            BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TO_CURRENCY_COLUMN_NAME,
            currencyPair.getTo().getCode(),
            DatabaseFilterType.EQUAL);
        break;
    }

    try {
      table.loadToMemory();

      for (DatabaseTableRecord record : table.getRecords()) {
        ExchangeRate exchangeRate = constructExchangeRateFromRecord(record);
        exchangeRateList.add(exchangeRate);
      }
    } catch (CantLoadTableToMemoryException e) {
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          "Failed to get History for currencyPair: " + currencyPair.toString(),
          "Couldn't load table to memory");
    } catch (CantCreateExchangeRateException e) {
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          "Failed to get History for currencyPair: " + currencyPair.toString(),
          "Couldn't create ExchangeRate object");
    }

    return exchangeRateList;
  }
  public List<ExchangeRate> getDailyExchangeRatesForPeriod(
      CurrencyPair currencyPair, long startTimestamp, long endTimestamp)
      throws CantGetExchangeRateException {
    List<ExchangeRate> exchangeRates = new ArrayList<>();

    String query =
        new StringBuilder()
            .append("SELECT * FROM ")
            .append(BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TABLE_NAME)
            .append(" WHERE ")
            .append(
                BitcoinVenezuelaProviderDatabaseConstants
                    .DAILY_EXCHANGE_RATES_FROM_CURRENCY_COLUMN_NAME)
            .append(" = '")
            .append(currencyPair.getFrom().getCode())
            .append("' AND ")
            .append(
                BitcoinVenezuelaProviderDatabaseConstants
                    .DAILY_EXCHANGE_RATES_TO_CURRENCY_COLUMN_NAME)
            .append(" = '")
            .append(currencyPair.getTo().getCode())
            .append("' ")
            .append(" AND ")
            .append(
                BitcoinVenezuelaProviderDatabaseConstants
                    .DAILY_EXCHANGE_RATES_TIMESTAMP_COLUMN_NAME)
            .append(" >= ")
            .append(startTimestamp)
            .append(" AND ")
            .append(
                BitcoinVenezuelaProviderDatabaseConstants
                    .DAILY_EXCHANGE_RATES_TIMESTAMP_COLUMN_NAME)
            .append(" <= ")
            .append(endTimestamp)
            .append(" ORDER BY ")
            .append(
                BitcoinVenezuelaProviderDatabaseConstants
                    .DAILY_EXCHANGE_RATES_TIMESTAMP_COLUMN_NAME)
            .append(" ASC ")
            .toString();

    DatabaseTable table =
        this.database.getTable(
            BitcoinVenezuelaProviderDatabaseConstants.DAILY_EXCHANGE_RATES_TABLE_NAME);

    try {
      for (DatabaseTableRecord record : table.customQuery(query, false))
        exchangeRates.add(constructExchangeRateFromRecord(record));
    } catch (CantLoadTableToMemoryException e) {
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          new StringBuilder()
              .append("Failed to get daily exchange rates for period: ")
              .append(startTimestamp)
              .append(" to ")
              .append(endTimestamp)
              .toString(),
          "Couldn't load table to memory");
    } catch (CantCreateExchangeRateException e) {
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          new StringBuilder()
              .append("Failed to get daily exchange rates for period: ")
              .append(startTimestamp)
              .append(" to ")
              .append(endTimestamp)
              .toString(),
          "Couldn't create ExchangeRate object");
    }

    return exchangeRates;
  }
  @Override
  public ExchangeRate getCurrentExchangeRate(CurrencyPair currencyPair)
      throws UnsupportedCurrencyPairException, CantGetExchangeRateException {

    if (!isCurrencyPairSupported(currencyPair)) throw new UnsupportedCurrencyPairException();

    String content, aux;
    JSONObject json;
    JSONArray jsonArr;
    double purchasePrice = 0;
    double salePrice = 0;
    try {
      content = HttpReader.getHTTPContent("http://api.bluelytics.com.ar/json/last_price");
      json = new JSONObject("{\"indexes\": " + content + "}");
      jsonArr = json.getJSONArray("indexes");

      for (int i = 0; i < jsonArr.length(); ++i) {
        JSONObject jsonIndex = jsonArr.getJSONObject(i);
        if (jsonIndex.getString("source").equals("elcronista")) {
          aux = jsonIndex.get("value_buy").toString();
          purchasePrice = Double.valueOf(aux);
          aux = jsonIndex.get("value_sell").toString();
          salePrice = Double.valueOf(aux);
          break;
        }
      }
    } catch (JSONException e) {
      errorManager.reportUnexpectedPluginException(
          Plugins.ELCRONISTA, UnexpectedPluginExceptionSeverity.DISABLES_THIS_PLUGIN, e);
      throw new CantGetExchangeRateException(
          CantGetExchangeRateException.DEFAULT_MESSAGE,
          e,
          "ElCronista CER Provider",
          "Cant Get exchange rate for"
              + currencyPair.getFrom().getCode()
              + "-"
              + currencyPair.getTo().getCode());
    }

    if (currencyPair.getTo() == FiatCurrency.US_DOLLAR) {
      purchasePrice = 1 / purchasePrice;
      salePrice = 1 / salePrice;
    }

    ExchangeRateImpl exchangeRate =
        new ExchangeRateImpl(
            currencyPair.getFrom(),
            currencyPair.getTo(),
            purchasePrice,
            salePrice,
            (new Date().getTime() / 1000));
    try {
      dao.saveExchangeRate(exchangeRate);
    } catch (CantSaveExchangeRateException e) {
      errorManager.reportUnexpectedPluginException(
          Plugins.ELCRONISTA,
          UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
          e);
    }
    return exchangeRate;
  }