diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java index 52ca301735..dd685ca0f9 100644 --- a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java @@ -30,6 +30,7 @@ import com.google.gson.JsonParseException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -69,6 +70,8 @@ public class ItemService private static final HttpUrl RS_PRICE_URL = HttpUrl.parse(BASE + "/api/graph"); private static final HttpUrl RS_SEARCH_URL = HttpUrl.parse(BASE + "/api/catalogue/items.json?category=1"); + private static final Duration CACHE_DUATION = Duration.ofMinutes(30); + private static final String CREATE_ITEMS = "CREATE TABLE IF NOT EXISTS `items` (\n" + " `id` int(11) NOT NULL,\n" + " `name` tinytext NOT NULL,\n" @@ -83,16 +86,15 @@ public class ItemService private static final String CREATE_PRICES = "CREATE TABLE IF NOT EXISTS `prices` (\n" + " `item` int(11) NOT NULL,\n" + " `price` int(11) NOT NULL,\n" - + " `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n" - + " KEY `item` (`item`)\n" + + " `time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n" + + " `fetched_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n" + + " UNIQUE KEY `item_time` (`item`,`time`),\n" + + " KEY `item_fetched_time` (`item`,`fetched_time`)\n" + ") ENGINE=InnoDB"; private static final String CREATE_PRICES_FK = "ALTER TABLE `prices`\n" + " ADD CONSTRAINT `item` FOREIGN KEY (`item`) REFERENCES `items` (`id`);"; - private static final String CREATE_PRICES_IDX = "ALTER TABLE `prices`\n" - + " ADD UNIQUE KEY `item` (`item`,`time`);"; - private static final String RUNELITE_CACHE = "RuneLite-Cache"; private final Sql2o sql2o; @@ -122,16 +124,6 @@ public class ItemService { // Ignore, happens when index already exists } - - try - { - con.createQuery(CREATE_PRICES_IDX) - .executeUpdate(); - } - catch (Sql2oException ex) - { - // Ignore - } } } @@ -234,9 +226,10 @@ public class ItemService } else { - Instant yesterday = now.minus(1, ChronoUnit.DAYS); - if (priceEntry == null || priceEntry.getTime().isBefore(yesterday)) + Instant cacheTime = now.minus(CACHE_DUATION); + if (priceEntry == null || priceEntry.getFetched_time().isBefore(cacheTime)) { + // Price is unknown, or was fetched too long ago List prices = fetchPrice(itemId); if (prices == null || prices.isEmpty()) @@ -244,6 +237,7 @@ public class ItemService return null; } + // Get the most recent price priceEntry = prices.get(prices.size() - 1); hit = false; } @@ -330,14 +324,14 @@ public class ItemService { if (time != null) { - return con.createQuery("select price, time from prices where item = :item and time <= :time order by time desc limit 1") + return con.createQuery("select item, price, time, fetched_time from prices where item = :item and time <= :time order by time desc limit 1") .addParameter("item", itemId) .addParameter("time", time.toString()) .executeAndFetchFirst(PriceEntry.class); } else { - return con.createQuery("select price, time from prices where item = :item order by time desc limit 1") + return con.createQuery("select item, price, time, fetched_time from prices where item = :item order by time desc limit 1") .addParameter("item", itemId) .executeAndFetchFirst(PriceEntry.class); } @@ -405,8 +399,10 @@ public class ItemService { RSPrices rsprice = fetchRSPrices(itemId); List entries = new ArrayList<>(); + Instant now = Instant.now(); - Query query = con.createQuery("insert ignore into prices (item, price, time) values (:item, :price, :time)"); + Query query = con.createQuery("insert into prices (item, price, time, fetched_time) values (:item, :price, :time, :fetched_time) " + + "ON DUPLICATE KEY UPDATE price = VALUES(price), fetched_time = VALUES(fetched_time)"); for (Entry entry : rsprice.getDaily().entrySet()) { @@ -419,12 +415,14 @@ public class ItemService priceEntry.setItem(itemId); priceEntry.setPrice(price); priceEntry.setTime(time); + priceEntry.setFetched_time(now); entries.add(priceEntry); query .addParameter("item", itemId) .addParameter("price", price) .addParameter("time", time) + .addParameter("fetched_time", now) .addToBatch(); } diff --git a/http-service/src/main/java/net/runelite/http/service/item/PriceEntry.java b/http-service/src/main/java/net/runelite/http/service/item/PriceEntry.java index 6f54d22ea3..6ae397ea67 100644 --- a/http-service/src/main/java/net/runelite/http/service/item/PriceEntry.java +++ b/http-service/src/main/java/net/runelite/http/service/item/PriceEntry.java @@ -31,6 +31,7 @@ public class PriceEntry private int item; private int price; private Instant time; + private Instant fetched_time; public int getItem() { @@ -61,4 +62,14 @@ public class PriceEntry { this.time = time; } + + public Instant getFetched_time() + { + return fetched_time; + } + + public void setFetched_time(Instant fetched_time) + { + this.fetched_time = fetched_time; + } }