# $Id: importNOS_Queries.rb 7602 2022-01-07 22:51:34Z flaterco $
# Functions for importNOS.rb:
# Database queries

# You can do thousands of queries or you can do one big query and build a
# hash in Ruby.  No clue which is better, and it's not important.

# Not well documented: each gives hashes while each_row gives arrays.

# Note that since all currents now use sidplus there is no risk of
# accidentally getting the wrong kind of station when looking up by sid.

# Look up name, state, and time zone by station ID in data_sets_old.
def getOldNameStateTz(db, sid)
  query = db.exec("select min(name), min(state), min(timezone) from data_sets_old where station_id = $1", [sid])
  query.values[0] == [nil, nil, nil] ? nil : query.values[0]
end

# Variant to match any bin for a current.
# If the name contains "(depth ...)" you get that with a random depth.
# N.B., min(name) tends to find the shorter name when different depths got
# different names due to the extra character used by deeper depths--but it's
# not guaranteed.
def getOldCurrentNameStateTz(db, sid)
  query = db.exec("select min(name), min(state), min(timezone) from data_sets_old where station_id like $1", [sid + "_%"])
  query.values[0] == [nil, nil, nil] ? nil : query.values[0]
end

# Look up new reference stations.
def getRefNameStateTz(db, sid)
  query = db.exec("select min(name), min(state), min(timezone) from reference_stations where station_id = $1", [sid])
  query.values[0] == [nil, nil, nil] ? nil : query.values[0]
end

# Again, match any bin for a current.
def getRefCurrentNameStateTz(db, sid)
  query = db.exec("select min(name), min(state), min(timezone) from reference_stations where station_id like $1", [sid + "_%"])
  query.values[0] == [nil, nil, nil] ? nil : query.values[0]
end

# Build a cheat sheet mapping 3D coordinates to states.
# If errors occur, consider replacing min with avg.
def getOldStateMap(db)
  stateMap = Hash.new
  query = db.exec("select min(lat), min(lng), min(state) from data_sets_old group by station_id")
  query.each_row {|row|
    stateMap[to_xyz(row[0].to_f, row[1].to_f)] = row[2]
  }
  stateMap
end

# This was helpful in CurSubs in 2020 when a lot of new stations had just
# been fixed up in CurRefs.
=begin
def getMergedStateMap(db)
  stateMap = Hash.new
  query = db.exec("select min(lat), min(lng), min(state) from data_sets_old group by station_id " +
                  "union " +
                  "select min(lat), min(lng), min(state) from data_sets group by station_id")
  query.each_row {|row|
    stateMap[to_xyz(row[0].to_f, row[1].to_f)] = row[2]
  }
  stateMap
end
=end

# Cache the constituent name aliases mapping for NOS.
def getConstituentAliases(db)
  aliases = Hash.new
  query = db.exec("select alias, name from aliases where format = 'NOS'")
  query.each_row {|row| aliases[row[0]] = row[1]}
  aliases
end

# Cache constituent speeds for validation.
def getSpeeds(db)
  speeds = Hash.new
  query = db.exec("select name, speed from constituents")
  query.each_row {|row| speeds[row[0]] = row[1].to_f}
  speeds
end

# Cache currents geogroups.  Returns empty hash if table does not exist.
def getCurrentsGeogroups(db)
  currentsGeogroups = Hash.new
  begin
    query = db.exec("select * from currents_geogroups")
    query.each_row {|row| currentsGeogroups[row[0]] = row[1..-1]}
  rescue PG::UndefinedTable
  end
  currentsGeogroups
end

# Does a station by this name exist?
def nameInUse(db, name)
  query = db.exec("select count(*) from data_sets where name = $1", [name])
  !query.getvalue(0,0).to_i.zero?
end

# Does a reference station with this station ID exist?
def refStationExists(db, sid)
  query = db.exec("select count(*) from reference_stations where station_id = $1", [sid])
  !query.getvalue(0,0).to_i.zero?
end

# Variant to allow for current bins.
def refCurrentStationExists(db, sid)
  query = db.exec("select count(*) from reference_stations where station_id like $1", [sid + "_%"])
  !query.getvalue(0,0).to_i.zero?
end

# Does a reference station with this name exist?
def refStationNamed(db, name)
  query = db.exec("select count(*) from reference_stations where name = $1", [name])
  !query.getvalue(0,0).to_i.zero?
end

# Get the time zone of a reference station.
def getRefTimezone(db, sid)
  query = db.exec("select timezone from reference_stations where station_id = $1", [sid])
  if query.ntuples != 1
    print "getRefTimezone: unexpected result querying on sid ", sid, "\n"
    raise "ntuples"
  end
  query.getvalue(0,0)
end

# Get the index of a reference station.
def getRefIndex(db, sid)
  query = db.exec("select index from reference_stations where station_id = $1", [sid])
  if query.ntuples != 1
    print "getRefIndex: unexpected result querying on sid ", sid, "\n"
    raise "ntuples"
  end
  query.getvalue(0,0)
end

# Return ids of western Aleutian stations in data_sets_old as an array.
def getWesternAleutians(db)
  query = db.exec("select distinct station_id from data_sets_old where state = 'AK' and lng > 0")
  query.column_values(0)
end
