-- PostgreSQL database dump
--
-\restrict HnyHE9wdHUeukhgNR1DDlycTFTTbv9pygL10rs3e3gZDrAeYEOJZ2ID4FIwBH1T
+\restrict 8o0t5OTJIfaTvsY8tJmP42PzP48zYSIzdnWkVDzdbzece2fzwS3EaVGiSKAGHZF
-- Dumped from database version 17.6 (Debian 17.6-0+deb13u1)
-- Dumped by pg_dump version 17.6 (Debian 17.6-0+deb13u1)
ALTER SEQUENCE public.api_keys_id_seq OWNED BY public.api_keys.id;
---
--- Name: checker_domains; Type: TABLE; Schema: public; Owner: -
---
-
-CREATE TABLE public.checker_domains (
- name text NOT NULL,
- checked_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
- status boolean NOT NULL
-);
-
-
--
-- Name: domains; Type: TABLE; Schema: public; Owner: -
--
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
block boolean DEFAULT true,
report_add_id uuid,
- report_remove_id uuid
+ report_remove_id uuid,
+ checked_at timestamp with time zone,
+ dead boolean DEFAULT false
);
ADD CONSTRAINT api_keys_pkey PRIMARY KEY (id);
---
--- Name: checker_domains checker_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.checker_domains
- ADD CONSTRAINT checker_domains_pkey PRIMARY KEY (name);
-
-
--
-- Name: domains domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
-- PostgreSQL database dump complete
--
-\unrestrict HnyHE9wdHUeukhgNR1DDlycTFTTbv9pygL10rs3e3gZDrAeYEOJZ2ID4FIwBH1T
+\unrestrict 8o0t5OTJIfaTvsY8tJmP42PzP48zYSIzdnWkVDzdbzece2fzwS3EaVGiSKAGHZF
stmt = (
sqlmodel
.select(
- checker.CheckerDomain.status,
+ domains.Domain.dead,
)
.where(
- checker.CheckerDomain.name == domain,
+ domains.Domain.name == domain,
)
)
- return self.db.fetch_one(stmt)
+ return not self.db.fetch_one(stmt)
.select(
domains.Domain.name,
)
- .join(
- CheckerDomain,
- domains.Domain.name == CheckerDomain.name,
- isouter=True,
- )
.where(
domains.Domain.removed_at == None,
# Only return domains that have not been checked or where the last check
# was at least 4 weeks ago
sqlmodel.or_(
- CheckerDomain.checked_at == None,
- CheckerDomain.checked_at <= cutoff,
+ domains.Domain.checked_at == None,
+ domains.Domain.checked_at <= cutoff,
),
)
.order_by(
- sqlmodel.nullsfirst(CheckerDomain.checked_at),
+ sqlmodel.nullsfirst(domains.Domain.checked_at),
domains.Domain.name,
)
)
Called after we have received a result for the queried domain
"""
# Fetch the domain name
- domain = self.results.pop(result)
+ name = self.results.pop(result)
# Fetch the result or raise any exceptions
try:
except dns.resolver.NoAnswer as e:
# If we have received no response, that does mean that we might not
# have found the root of the domain, but something at least responded.
- status = True
+ dead = False
# NXDOMAIN
except dns.resolver.NXDOMAIN as e:
- status = False
+ dead = True
# SERVFAIL
except dns.resolver.NoNameservers as e:
- status = False
+ dead = True
# Raise any other exception
except Exception as e:
# There has been no exception, the query returned some data
else:
- status = True
+ dead = False
- log.debug("Storing result for %s..." % domain)
+ log.debug("Storing result for %s..." % name)
stmt = (
- sqlalchemy.dialects.postgresql
- .insert(
- CheckerDomain,
+ sqlmodel
+ .update(
+ domains.Domain,
+ )
+ .where(
+ # The name must match
+ domains.Domain.name == name,
+
+ # Don't mess with removed domains
+ domains.Domain.removed_at == None,
)
.values({
- "name" : domain,
- "status" : status,
+ "checked_at" : sqlmodel.func.current_timestamp(),
+ "dead" : dead,
})
- .on_conflict_do_update(
- index_elements = [
- CheckerDomain.name,
- ],
- set_ = {
- "checked_at" : sqlmodel.func.current_timestamp(),
- }
- )
)
# Store the result
self.backend.db.execute(stmt)
-
-
-class CheckerDomain(sqlmodel.SQLModel, database.BackendMixin, table=True):
- __tablename__ = "checker_domains"
-
- # Name
- name: str = sqlmodel.Field(primary_key=True)
-
- # Checked At
- checked_at : datetime.datetime = sqlmodel.Field(
- sa_column_kwargs = {"server_default" : sqlmodel.text("CURRENT_TIMESTAMP")}
- )
-
- # Status
- status : bool
# Log action
log.info("%s (block = %s) has been removed from %s" % (self.name, self.block, self.list))
+ # Checked At
+ checked_at: datetime.datetime | None = None
+
+ # Dead?
+ dead: bool = False
+
class DomainEvent(sqlmodel.SQLModel, table=True):
"""
.select(
domains.Domain,
)
- .join(
- checker.CheckerDomain,
- checker.CheckerDomain.name == domains.Domain.name,
- isouter=True,
- )
.where(
# Select only domains from this list
domains.Domain.list == self,
# Ignore domains that have been removed
domains.Domain.removed_at == None,
- # Only select domains that have been checked positive
+ # Only select domains that are not dead
# or have not been checked, yet.
sqlmodel.or_(
- checker.CheckerDomain.status == None,
- checker.CheckerDomain.status == True,
+ domains.Domain.dead == None,
+ domains.Domain.dead == False,
),
)
.cte("blocked_domains")
.select_from(
domains.Domain,
)
- .join(
- checker.CheckerDomain,
- checker.CheckerDomain.name == domains.Domain.name,
- )
.where(
domains.Domain.source == self,
domains.Domain.removed_at == None,
# Only check dead domains
- checker.CheckerDomain.status == False,
+ domains.Domain.dead == True,
)
)