001/* 002 * Stallion Core: A Modern Web Framework 003 * 004 * Copyright (C) 2015 - 2016 Stallion Software LLC. 005 * 006 * This program is free software: you can redistribute it and/or modify it under the terms of the 007 * GNU General Public License as published by the Free Software Foundation, either version 2 of 008 * the License, or (at your option) any later version. This program is distributed in the hope that 009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 011 * License for more details. You should have received a copy of the GNU General Public License 012 * along with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>. 013 * 014 * 015 * 016 */ 017 018package io.stallion.dataAccess.db.postgres; 019 020import io.stallion.dataAccess.db.DB; 021import io.stallion.dataAccess.Tickets; 022import io.stallion.services.Log; 023import org.apache.commons.dbutils.QueryRunner; 024import org.apache.commons.dbutils.handlers.ScalarHandler; 025 026import java.sql.SQLException; 027import java.util.Queue; 028import java.util.concurrent.ConcurrentLinkedQueue; 029 030 031public class PostgresTickets implements Tickets { 032 private Queue<Long> loadedIds; 033 private DB db; 034 035 036 public PostgresTickets(DB db) { 037 this.db = db; 038 loadedIds = new ConcurrentLinkedQueue<Long>(); 039 createSequence(); 040 try { 041 refillQueue(); 042 } catch (SQLException e) { 043 throw new RuntimeException(e); 044 } 045 } 046 047 public Long nextId() { 048 for (int x=0; x<20; x++) { 049 Long id = loadedIds.poll(); 050 if (id != null) { 051 return id; 052 } else { 053 try { 054 refillQueue(); 055 } catch (Exception e) { 056 Log.exception(e, "Error refilling queue"); 057 try { 058 Thread.sleep(500); 059 } catch (Exception ex) { 060 throw new RuntimeException(e); 061 } 062 } 063 } 064 } 065 throw new RuntimeException("Could not load the next ticket"); 066 } 067 068 public void createSequence() { 069 QueryRunner q = db.newQuery(); 070 try { 071 q.update("CREATE SEQUENCE stallion_tickets_seq INCREMENT BY 300 MINVALUE 100000;"); 072 } catch(Exception e) { 073 Log.info("Sequence already exists"); 074 } 075 } 076 077 public void refillQueue() throws SQLException { 078 QueryRunner q = db.newQuery(); 079 ScalarHandler<Long> scalar = new ScalarHandler<Long>(); 080 Long nextId = q.query("SELECT nextval('stallion_tickets_seq')", scalar); 081 for (int x= 0; x < 300; x++ ) { 082 loadedIds.add(nextId + x); 083 } 084 } 085}