feat(station): MY_IOTA in the station profile

IOTA is an official ADIF field, and almost everything for it was already here:
the qso table has carried my_iota since the first migration, the insert and scan
handle it, and both ADIF import and export write it. The one missing link was
the station profile, so the reference had to be typed on every contact of an
island activation, or added afterwards in a bulk edit.

Migration 0025 adds the column; it joins my_sota_ref and my_pota_ref in the
profile, in the Station Information panel, and in the same stamp-if-empty block
that fills the other My* fields on a logged QSO.

Uppercased and trimmed on save. ADIF spells it EU-005, and an operator typing
"eu-005" would otherwise put a reference no award matcher recognises on every
QSO of an activation - the kind of mistake you only find months later.
This commit is contained in:
2026-08-10 19:28:07 +02:00
parent 0d48dbfd17
commit ae7472a67d
8 changed files with 44 additions and 14 deletions
+10
View File
@@ -541,6 +541,8 @@ type StationSettings struct {
MyCountry string `json:"my_country"` MyCountry string `json:"my_country"`
MySOTARef string `json:"my_sota_ref"` MySOTARef string `json:"my_sota_ref"`
MyPOTARef string `json:"my_pota_ref"` MyPOTARef string `json:"my_pota_ref"`
// MyIOTA is the island the station operates FROM (ADIF MY_IOTA), e.g. EU-005.
MyIOTA string `json:"my_iota"`
} }
// LookupSettings is the JSON shape exchanged with the frontend. // LookupSettings is the JSON shape exchanged with the frontend.
@@ -3033,6 +3035,9 @@ func (a *App) applyStationDefaults(q *qso.QSO, includeIdentity bool) {
if q.MyPOTARef == "" { if q.MyPOTARef == "" {
q.MyPOTARef = p.MyPOTARef q.MyPOTARef = p.MyPOTARef
} }
if q.MyIOTA == "" {
q.MyIOTA = p.MyIOTA
}
// MY_NAME = the operator's personal name (profile OpName, e.g. "Greg") — stamped // MY_NAME = the operator's personal name (profile OpName, e.g. "Greg") — stamped
// like the other My* fields so every QSO carries it, not just those edited by hand. // like the other My* fields so every QSO carries it, not just those edited by hand.
if q.MyName == "" { if q.MyName == "" {
@@ -13464,6 +13469,7 @@ func (a *App) GetStationSettings() (StationSettings, error) {
MyCountry: p.MyCountry, MyCountry: p.MyCountry,
MySOTARef: p.MySOTARef, MySOTARef: p.MySOTARef,
MyPOTARef: p.MyPOTARef, MyPOTARef: p.MyPOTARef,
MyIOTA: p.MyIOTA,
}, nil }, nil
} }
@@ -13561,6 +13567,10 @@ func (a *App) SaveStationSettings(s StationSettings) error {
p.MyCountry = s.MyCountry p.MyCountry = s.MyCountry
p.MySOTARef = s.MySOTARef p.MySOTARef = s.MySOTARef
p.MyPOTARef = s.MyPOTARef p.MyPOTARef = s.MyPOTARef
// Uppercased on the way in: ADIF spells it EU-005, and an operator typing
// "eu-005" would otherwise put a reference no award matcher recognises on
// every QSO of an activation.
p.MyIOTA = strings.ToUpper(strings.TrimSpace(s.MyIOTA))
return a.profiles.Save(a.ctx, &p) return a.profiles.Save(a.ctx, &p)
} }
+4 -2
View File
@@ -5,12 +5,14 @@
"en": [ "en": [
"DX cluster: an L badge next to a callsign marks a station that uploads to LoTW, with a matching LoTW users only filter, and a Spotter continent filter narrows the list by where the spot came FROM — a JA report on 20 m tells a European little about their own path. The filter panel has been tidied along one rule: a switch is a behaviour you turn on or off, chips pick any number from a set. Nothing appears in both shapes any more, the Lock buttons sit in the heading of the section they lock, every section can be cleared the same way, and the whole panel is finally translated.", "DX cluster: an L badge next to a callsign marks a station that uploads to LoTW, with a matching LoTW users only filter, and a Spotter continent filter narrows the list by where the spot came FROM — a JA report on 20 m tells a European little about their own path. The filter panel has been tidied along one rule: a switch is a behaviour you turn on or off, chips pick any number from a set. Nothing appears in both shapes any more, the Lock buttons sit in the heading of the section they lock, every section can be cleared the same way, and the whole panel is finally translated.",
"DX cluster: the Spotter continent filter now actually matches. RBN skimmers report as VU2OY-# and cluster nodes as DL1ABC-2, and the suffix was passed straight to the prefix lookup, so every spot came back with no continent and the filter silently selected nothing.", "DX cluster: the Spotter continent filter now actually matches. RBN skimmers report as VU2OY-# and cluster nodes as DL1ABC-2, and the suffix was passed straight to the prefix lookup, so every spot came back with no continent and the filter silently selected nothing.",
"A spot now stops being NEW the moment you log it. Logging announced the QSO but never dropped the cluster worked-index snapshot, so the refresh that follows re-read the answer computed BEFORE the contact — a station stayed yellow on the band map and in the cluster with the QSO plainly in the log, until something else happened to rebuild the index." "A spot now stops being NEW the moment you log it. Logging announced the QSO but never dropped the cluster worked-index snapshot, so the refresh that follows re-read the answer computed BEFORE the contact — a station stayed yellow on the band map and in the cluster with the QSO plainly in the log, until something else happened to rebuild the index.",
"Station information gains an IOTA field (ADIF MY_IOTA, e.g. EU-005), stamped on every QSO like the SOTA and POTA references beside it. The QSO table has carried the field since the first release and both ADIF import and export already handled it — only the station profile could not supply it, so an island activation meant typing the reference on every contact."
], ],
"fr": [ "fr": [
"Cluster DX : un badge L à côté de l indicatif signale une station qui utilise LoTW, avec le filtre Utilisateurs LoTW seulement qui va avec, et un filtre Continent du spotter restreint selon l origine du spot — un report JA sur 20 m dit peu de chose à un Européen sur son propre chemin. Le panneau de filtres a été remis d aplomb selon une seule règle : un interrupteur est un comportement qu on active ou non, les pastilles choisissent dans un ensemble. Plus rien n existe sous les deux formes, les boutons de verrouillage sont dans le titre de la section qu ils verrouillent, chaque section s efface de la même façon, et le panneau est enfin traduit.", "Cluster DX : un badge L à côté de l indicatif signale une station qui utilise LoTW, avec le filtre Utilisateurs LoTW seulement qui va avec, et un filtre Continent du spotter restreint selon l origine du spot — un report JA sur 20 m dit peu de chose à un Européen sur son propre chemin. Le panneau de filtres a été remis d aplomb selon une seule règle : un interrupteur est un comportement qu on active ou non, les pastilles choisissent dans un ensemble. Plus rien n existe sous les deux formes, les boutons de verrouillage sont dans le titre de la section qu ils verrouillent, chaque section s efface de la même façon, et le panneau est enfin traduit.",
"Cluster DX : le filtre Continent du spotter fonctionne enfin. Les skimmers RBN s annoncent en VU2OY-# et les nœuds cluster en DL1ABC-2, et ce suffixe partait tel quel dans la recherche de préfixe — tous les spots revenaient sans continent et le filtre ne sélectionnait rien.", "Cluster DX : le filtre Continent du spotter fonctionne enfin. Les skimmers RBN s annoncent en VU2OY-# et les nœuds cluster en DL1ABC-2, et ce suffixe partait tel quel dans la recherche de préfixe — tous les spots revenaient sans continent et le filtre ne sélectionnait rien.",
"Un spot cesse enfin d être NOUVEAU dès que tu l enregistres. La journalisation annonçait le QSO mais ne vidait jamais l instantané de l index des contacts, donc le rafraîchissement qui suit relisait la réponse calculée AVANT le contact — une station restait jaune sur le bandmap et dans le cluster alors que le QSO était bien au log, jusqu à ce qu autre chose reconstruise l index." "Un spot cesse enfin d être NOUVEAU dès que tu l enregistres. La journalisation annonçait le QSO mais ne vidait jamais l instantané de l index des contacts, donc le rafraîchissement qui suit relisait la réponse calculée AVANT le contact — une station restait jaune sur le bandmap et dans le cluster alors que le QSO était bien au log, jusqu à ce qu autre chose reconstruise l index.",
"Les informations station gagnent un champ IOTA (MY_IOTA en ADIF, par exemple EU-005), estampillé sur chaque QSO comme les références SOTA et POTA à côté. La table des QSO portait le champ depuis la première version et l import comme l export ADIF le géraient déjà — seul le profil station ne savait pas le fournir, donc une activation d île obligeait à retaper la référence à chaque contact."
] ]
}, },
{ {
+1 -1
View File
@@ -1933,7 +1933,7 @@ export default function App() {
// === Station === // === Station ===
const [station, setStation] = useState<StationSettings>({ const [station, setStation] = useState<StationSettings>({
callsign: '', operator: '', callsign: '', operator: '',
my_grid: '', my_country: '', my_sota_ref: '', my_pota_ref: '', my_grid: '', my_country: '', my_sota_ref: '', my_pota_ref: '', my_iota: '',
}); });
const [showFirstRun, setShowFirstRun] = useState(false); const [showFirstRun, setShowFirstRun] = useState(false);
myCallRef.current = (station.callsign || '').toUpperCase(); myCallRef.current = (station.callsign || '').toUpperCase();
+6 -1
View File
@@ -144,7 +144,7 @@ const emptyProfile = (): Profile => ({
my_grid: '', my_country: '', my_grid: '', my_country: '',
my_state: '', my_cnty: '', my_state: '', my_cnty: '',
my_street: '', my_city: '', my_postal_code: '', my_street: '', my_city: '', my_postal_code: '',
my_sota_ref: '', my_pota_ref: '', my_sota_ref: '', my_pota_ref: '', my_iota: '',
my_rig: '', my_antenna: '', my_rig: '', my_antenna: '',
tx_pwr: undefined, tx_pwr: undefined,
is_active: false, is_active: false,
@@ -1854,6 +1854,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
my_grid: (activeProfile.my_grid ?? '').trim().toUpperCase(), my_grid: (activeProfile.my_grid ?? '').trim().toUpperCase(),
my_sota_ref: (activeProfile.my_sota_ref ?? '').trim().toUpperCase(), my_sota_ref: (activeProfile.my_sota_ref ?? '').trim().toUpperCase(),
my_pota_ref: (activeProfile.my_pota_ref ?? '').trim().toUpperCase(), my_pota_ref: (activeProfile.my_pota_ref ?? '').trim().toUpperCase(),
my_iota: (activeProfile.my_iota ?? '').trim().toUpperCase(),
} as any); } as any);
} }
await SaveLookupSettings(lookup as any); await SaveLookupSettings(lookup as any);
@@ -2013,6 +2014,10 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
<Label>{t('station.pota')}</Label> <Label>{t('station.pota')}</Label>
<Input className="font-mono uppercase" value={p.my_pota_ref ?? ''} onChange={(e) => updateActive({ my_pota_ref: e.target.value })} placeholder="FF-1234" /> <Input className="font-mono uppercase" value={p.my_pota_ref ?? ''} onChange={(e) => updateActive({ my_pota_ref: e.target.value })} placeholder="FF-1234" />
</div> </div>
<div className="space-y-1">
<Label>{t('station.iota')}</Label>
<Input className="font-mono uppercase" value={p.my_iota ?? ''} onChange={(e) => updateActive({ my_iota: e.target.value })} placeholder="EU-005" />
</div>
</div> </div>
</> </>
); );
+2 -2
View File
@@ -222,7 +222,7 @@ const en: Dict = {
'station.autofill': 'Auto-filled from the callsign — editable (stamped as MY_* on each QSO)', 'station.autofill': 'Auto-filled from the callsign — editable (stamped as MY_* on each QSO)',
'station.myGrid': 'My grid', 'station.myCountry': 'My country', 'station.dxcc': 'DXCC #', 'station.cqz': 'CQ zone', 'station.ituz': 'ITU zone', 'station.myGrid': 'My grid', 'station.myCountry': 'My country', 'station.dxcc': 'DXCC #', 'station.cqz': 'CQ zone', 'station.ituz': 'ITU zone',
'station.lat': 'Latitude', 'station.lon': 'Longitude', 'station.state': 'State / pref', 'station.county': 'County', 'station.lat': 'Latitude', 'station.lon': 'Longitude', 'station.state': 'State / pref', 'station.county': 'County',
'station.street': 'Street address', 'station.postal': 'Postal code', 'station.city': 'City', 'station.sota': 'SOTA ref', 'station.pota': 'POTA ref', 'station.street': 'Street address', 'station.postal': 'Postal code', 'station.city': 'City', 'station.sota': 'SOTA ref', 'station.iota': 'IOTA (my island)', 'station.pota': 'POTA ref',
// Confirmations panel // Confirmations panel
'conf.hint': 'Default QSL / eQSL / LoTW / upload status applied to every QSO you log — manually or via UDP auto-log from WSJT-X / JTDX / MSHV. Leave a field blank to keep the QSO column empty.', 'conf.hint': 'Default QSL / eQSL / LoTW / upload status applied to every QSO you log — manually or via UDP auto-log from WSJT-X / JTDX / MSHV. Leave a field blank to keep the QSO column empty.',
'conf.sent': 'Sent', 'conf.rcvd': 'Rcvd', 'conf.paperQsl': 'Paper QSL', 'conf.sent': 'Sent', 'conf.rcvd': 'Rcvd', 'conf.paperQsl': 'Paper QSL',
@@ -647,7 +647,7 @@ const fr: Dict = {
'station.autofill': "Auto-rempli depuis l'indicatif — éditable (inscrit en MY_* sur chaque QSO)", 'station.autofill': "Auto-rempli depuis l'indicatif — éditable (inscrit en MY_* sur chaque QSO)",
'station.myGrid': 'Mon locator', 'station.myCountry': 'Mon pays', 'station.dxcc': 'DXCC #', 'station.cqz': 'Zone CQ', 'station.ituz': 'Zone ITU', 'station.myGrid': 'Mon locator', 'station.myCountry': 'Mon pays', 'station.dxcc': 'DXCC #', 'station.cqz': 'Zone CQ', 'station.ituz': 'Zone ITU',
'station.lat': 'Latitude', 'station.lon': 'Longitude', 'station.state': 'État / préf', 'station.county': 'Comté', 'station.lat': 'Latitude', 'station.lon': 'Longitude', 'station.state': 'État / préf', 'station.county': 'Comté',
'station.street': 'Adresse', 'station.postal': 'Code postal', 'station.city': 'Ville', 'station.sota': 'Réf SOTA', 'station.pota': 'Réf POTA', 'station.street': 'Adresse', 'station.postal': 'Code postal', 'station.city': 'Ville', 'station.sota': 'Réf SOTA', 'station.iota': 'IOTA (mon île)', 'station.pota': 'Réf POTA',
'conf.hint': 'Statut QSL / eQSL / LoTW / upload par défaut appliqué à chaque QSO enregistré — manuellement ou via auto-log UDP depuis WSJT-X / JTDX / MSHV. Laisse un champ vide pour garder la colonne du QSO vide.', 'conf.hint': 'Statut QSL / eQSL / LoTW / upload par défaut appliqué à chaque QSO enregistré — manuellement ou via auto-log UDP depuis WSJT-X / JTDX / MSHV. Laisse un champ vide pour garder la colonne du QSO vide.',
'conf.sent': 'Envoyée', 'conf.rcvd': 'Reçue', 'conf.paperQsl': 'QSL papier', 'conf.sent': 'Envoyée', 'conf.rcvd': 'Reçue', 'conf.paperQsl': 'QSL papier',
'conf.note': '« Envoyée » = statut d\'upload du QSO vers le service ; « N » est typique pour qu\'OpsLog suive les QSO restant à uploader. Club Log & HRDLog sont upload-only (pas de « reçue » en ADIF) ; QRZ.com a aussi « Reçue » = confirmé en retour.', 'conf.note': '« Envoyée » = statut d\'upload du QSO vers le service ; « N » est typique pour qu\'OpsLog suive les QSO restant à uploader. Club Log & HRDLog sont upload-only (pas de « reçue » en ADIF) ; QRZ.com a aussi « Reçue » = confirmé en retour.',
+4
View File
@@ -3176,6 +3176,7 @@ export namespace main {
my_country: string; my_country: string;
my_sota_ref: string; my_sota_ref: string;
my_pota_ref: string; my_pota_ref: string;
my_iota: string;
static createFrom(source: any = {}) { static createFrom(source: any = {}) {
return new StationSettings(source); return new StationSettings(source);
@@ -3189,6 +3190,7 @@ export namespace main {
this.my_country = source["my_country"]; this.my_country = source["my_country"];
this.my_sota_ref = source["my_sota_ref"]; this.my_sota_ref = source["my_sota_ref"];
this.my_pota_ref = source["my_pota_ref"]; this.my_pota_ref = source["my_pota_ref"];
this.my_iota = source["my_iota"];
} }
} }
export class StationTestResult { export class StationTestResult {
@@ -3713,6 +3715,7 @@ export namespace profile {
my_city: string; my_city: string;
my_postal_code: string; my_postal_code: string;
my_sota_ref: string; my_sota_ref: string;
my_iota: string;
my_pota_ref: string; my_pota_ref: string;
my_rig: string; my_rig: string;
my_antenna: string; my_antenna: string;
@@ -3750,6 +3753,7 @@ export namespace profile {
this.my_city = source["my_city"]; this.my_city = source["my_city"];
this.my_postal_code = source["my_postal_code"]; this.my_postal_code = source["my_postal_code"];
this.my_sota_ref = source["my_sota_ref"]; this.my_sota_ref = source["my_sota_ref"];
this.my_iota = source["my_iota"];
this.my_pota_ref = source["my_pota_ref"]; this.my_pota_ref = source["my_pota_ref"];
this.my_rig = source["my_rig"]; this.my_rig = source["my_rig"];
this.my_antenna = source["my_antenna"]; this.my_antenna = source["my_antenna"];
@@ -0,0 +1,7 @@
-- MY_IOTA: the island reference the station operates FROM, e.g. "EU-005".
--
-- An official ADIF field, and the QSO table has carried my_iota since 0001 —
-- only the station profile could not supply it, so an island activation had to
-- have the reference typed on every contact or added afterwards. Blank by
-- default: the overwhelming majority of stations are not on an island.
ALTER TABLE station_profiles ADD COLUMN my_iota TEXT NOT NULL DEFAULT '';
+10 -8
View File
@@ -52,6 +52,7 @@ type Profile struct {
MyCity string `json:"my_city"` MyCity string `json:"my_city"`
MyPostalCode string `json:"my_postal_code"` MyPostalCode string `json:"my_postal_code"`
MySOTARef string `json:"my_sota_ref"` MySOTARef string `json:"my_sota_ref"`
MyIOTA string `json:"my_iota"`
MyPOTARef string `json:"my_pota_ref"` MyPOTARef string `json:"my_pota_ref"`
MyRig string `json:"my_rig"` MyRig string `json:"my_rig"`
MyAntenna string `json:"my_antenna"` MyAntenna string `json:"my_antenna"`
@@ -75,7 +76,7 @@ type Repo struct{ db *sql.DB }
func NewRepo(db *sql.DB) *Repo { return &Repo{db: db} } func NewRepo(db *sql.DB) *Repo { return &Repo{db: db} }
const selectCols = `id, name, callsign, operator, op_name, owner_callsign, my_grid, my_country, my_state, my_cnty, const selectCols = `id, name, callsign, operator, op_name, owner_callsign, my_grid, my_country, my_state, my_cnty,
my_street, my_city, my_postal_code, my_sota_ref, my_pota_ref, my_street, my_city, my_postal_code, my_sota_ref, my_pota_ref, my_iota,
my_rig, my_antenna, my_dxcc, my_cqz, my_ituz, my_lat, my_lon, tx_pwr, my_rig, my_antenna, my_dxcc, my_cqz, my_ituz, my_lat, my_lon, tx_pwr,
is_active, sort_order, db_config, created_at, updated_at` is_active, sort_order, db_config, created_at, updated_at`
@@ -124,12 +125,12 @@ func (r *Repo) Save(ctx context.Context, p *Profile) error {
res, err := r.db.ExecContext(ctx, ` res, err := r.db.ExecContext(ctx, `
INSERT INTO station_profiles INSERT INTO station_profiles
(name, callsign, operator, op_name, owner_callsign, my_grid, my_country, my_state, my_cnty, (name, callsign, operator, op_name, owner_callsign, my_grid, my_country, my_state, my_cnty,
my_street, my_city, my_postal_code, my_sota_ref, my_pota_ref, my_street, my_city, my_postal_code, my_sota_ref, my_pota_ref, my_iota,
my_rig, my_antenna, my_dxcc, my_cqz, my_ituz, my_lat, my_lon, tx_pwr, my_rig, my_antenna, my_dxcc, my_cqz, my_ituz, my_lat, my_lon, tx_pwr,
is_active, sort_order, created_at, updated_at) is_active, sort_order, created_at, updated_at)
VALUES(?,?,?,?,?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?,?,?,?, ?,?,?,?)`, VALUES(?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?,?,?, ?,?,?,?)`,
p.Name, p.Callsign, p.Operator, p.OpName, p.OwnerCallsign, p.MyGrid, p.MyCountry, p.MyState, p.MyCounty, p.Name, p.Callsign, p.Operator, p.OpName, p.OwnerCallsign, p.MyGrid, p.MyCountry, p.MyState, p.MyCounty,
p.MyStreet, p.MyCity, p.MyPostalCode, p.MySOTARef, p.MyPOTARef, p.MyStreet, p.MyCity, p.MyPostalCode, p.MySOTARef, p.MyPOTARef, p.MyIOTA,
p.MyRig, p.MyAntenna, nullableInt(p.MyDXCC), nullableInt(p.MyCQZone), nullableInt(p.MyITUZone), p.MyRig, p.MyAntenna, nullableInt(p.MyDXCC), nullableInt(p.MyCQZone), nullableInt(p.MyITUZone),
nullableFloat(p.MyLat), nullableFloat(p.MyLon), nullableFloat(p.TxPower), nullableFloat(p.MyLat), nullableFloat(p.MyLon), nullableFloat(p.TxPower),
boolInt(p.IsActive), p.SortOrder, now, now) boolInt(p.IsActive), p.SortOrder, now, now)
@@ -144,13 +145,13 @@ func (r *Repo) Save(ctx context.Context, p *Profile) error {
UPDATE station_profiles SET UPDATE station_profiles SET
name = ?, callsign = ?, operator = ?, op_name = ?, owner_callsign = ?, my_grid = ?, my_country = ?, name = ?, callsign = ?, operator = ?, op_name = ?, owner_callsign = ?, my_grid = ?, my_country = ?,
my_state = ?, my_cnty = ?, my_street = ?, my_city = ?, my_postal_code = ?, my_state = ?, my_cnty = ?, my_street = ?, my_city = ?, my_postal_code = ?,
my_sota_ref = ?, my_pota_ref = ?, my_rig = ?, my_antenna = ?, my_sota_ref = ?, my_pota_ref = ?, my_iota = ?, my_rig = ?, my_antenna = ?,
my_dxcc = ?, my_cqz = ?, my_ituz = ?, my_lat = ?, my_lon = ?, tx_pwr = ?, my_dxcc = ?, my_cqz = ?, my_ituz = ?, my_lat = ?, my_lon = ?, tx_pwr = ?,
sort_order = ?, updated_at = ? sort_order = ?, updated_at = ?
WHERE id = ?`, WHERE id = ?`,
p.Name, p.Callsign, p.Operator, p.OpName, p.OwnerCallsign, p.MyGrid, p.MyCountry, p.Name, p.Callsign, p.Operator, p.OpName, p.OwnerCallsign, p.MyGrid, p.MyCountry,
p.MyState, p.MyCounty, p.MyStreet, p.MyCity, p.MyPostalCode, p.MyState, p.MyCounty, p.MyStreet, p.MyCity, p.MyPostalCode,
p.MySOTARef, p.MyPOTARef, p.MyRig, p.MyAntenna, p.MySOTARef, p.MyPOTARef, p.MyIOTA, p.MyRig, p.MyAntenna,
nullableInt(p.MyDXCC), nullableInt(p.MyCQZone), nullableInt(p.MyITUZone), nullableInt(p.MyDXCC), nullableInt(p.MyCQZone), nullableInt(p.MyITUZone),
nullableFloat(p.MyLat), nullableFloat(p.MyLon), nullableFloat(p.TxPower), nullableFloat(p.MyLat), nullableFloat(p.MyLon), nullableFloat(p.TxPower),
p.SortOrder, now, p.ID) p.SortOrder, now, p.ID)
@@ -264,7 +265,7 @@ func scan(row scannable) (Profile, error) {
var p Profile var p Profile
var ( var (
callsign, operator, opName, ownerCall, myGrid, myCountry, myState, myCnty, callsign, operator, opName, ownerCall, myGrid, myCountry, myState, myCnty,
myStreet, myCity, myPostal, mySOTA, myPOTA, myStreet, myCity, myPostal, mySOTA, myPOTA, myIOTA,
myRig, myAntenna sql.NullString myRig, myAntenna sql.NullString
myDXCC, myCQZ, myITUZ sql.NullInt64 myDXCC, myCQZ, myITUZ sql.NullInt64
myLat, myLon, txPwr sql.NullFloat64 myLat, myLon, txPwr sql.NullFloat64
@@ -273,7 +274,7 @@ func scan(row scannable) (Profile, error) {
createdAt, updatedAt string createdAt, updatedAt string
) )
err := row.Scan(&p.ID, &p.Name, &callsign, &operator, &opName, &ownerCall, &myGrid, &myCountry, &myState, &myCnty, err := row.Scan(&p.ID, &p.Name, &callsign, &operator, &opName, &ownerCall, &myGrid, &myCountry, &myState, &myCnty,
&myStreet, &myCity, &myPostal, &mySOTA, &myPOTA, &myStreet, &myCity, &myPostal, &mySOTA, &myPOTA, &myIOTA,
&myRig, &myAntenna, &myDXCC, &myCQZ, &myITUZ, &myLat, &myLon, &txPwr, &myRig, &myAntenna, &myDXCC, &myCQZ, &myITUZ, &myLat, &myLon, &txPwr,
&isActive, &sortOrder, &dbConfig, &createdAt, &updatedAt) &isActive, &sortOrder, &dbConfig, &createdAt, &updatedAt)
if err != nil { if err != nil {
@@ -294,6 +295,7 @@ func scan(row scannable) (Profile, error) {
p.MyCity = myCity.String p.MyCity = myCity.String
p.MyPostalCode = myPostal.String p.MyPostalCode = myPostal.String
p.MySOTARef = mySOTA.String p.MySOTARef = mySOTA.String
p.MyIOTA = myIOTA.String
p.MyPOTARef = myPOTA.String p.MyPOTARef = myPOTA.String
p.MyRig = myRig.String p.MyRig = myRig.String
p.MyAntenna = myAntenna.String p.MyAntenna = myAntenna.String