# frozen_string_literal: true require 'georuby' require 'sequel' require 'sequel-postgis-georuby' require 'singleton' module TacScribe # Acts as the interface to the back-end datastore and hides all datastore # implementation details from callers. Note that ruby does not support # exception chaining we are not wrapping exceptions yet. This will happen # when https://bugs.ruby-lang.org/issues/8257 is fixed. class Datastore include Singleton include GeoRuby::SimpleFeatures attr_accessor :db, :written, :deleted @configuration = nil @db = nil def configuration @configuration ||= Configuration.new end def configure configuration yield(@configuration) if block_given? end # Contains all the connection configuration required for connectin # to a postgresql database. Defaults to localhost with ubuntu presets class Configuration attr_accessor :host, :port, :database, :username, :password def initialize @host = 'localhost' @port = '5432' @database = 'tac_scribe' @username = 'tac_scribe' @password = 'tac_scribe' end end def connect configure @db = Sequel.connect(connection_string, max_connections: 49) @db.extension :postgis_georuby end def truncate_table @db[:units].truncate end def write_objects(objects) @db[:units].insert_conflict( constraint: :units_pkey, update: { position: Sequel[:excluded][:position], altitude: Sequel[:excluded][:altitude], heading: Sequel[:excluded][:heading], updated_at: Sequel[:excluded][:updated_at], deleted: Sequel[:excluded][:deleted] } ) .multi_insert(objects) deleted_ids = @db[:units].where(deleted: true).select_map(:id) @db[:units].where(deleted: true).delete self.written = objects.size self.deleted = deleted_ids.size deleted_ids end private def connection_string if RUBY_PLATFORM == 'java' "jdbc:postgresql://#{@configuration.host}:#{@configuration.port}/" \ "#{@configuration.database}?user=#{@configuration.username}&" \ "password=#{configuration.password}" else "postgres://#{@configuration.username}:#{@configuration.password}@" \ "#{@configuration.host}:#{@configuration.port}" \ "/#{@configuration.database}" end end end end