]> gitweb @ CieloNegro.org - blackboard-dns.git/blobdiff - DDNS/Zone.hs
editzone
[blackboard-dns.git] / DDNS / Zone.hs
index e5d4af519a3ef2ed485f958324366f1d1a76f839..c4207a3c6aec4ce60221fd80e6850b74763bbe06 100644 (file)
@@ -3,13 +3,14 @@ module DDNS.Zone
     , completeZoneName
 
     , getZone
+    , putZone
     )
     where
 
 import           Control.Monad
 import           Control.Monad.Trans
 import           Data.List
-import           Database.HaskellDB
+import           Database.HaskellDB as DB
 import qualified DDNS.DB.Zones as Zones
 import           Network.DNS.Message
 import           System.Console.Haskeline
@@ -58,4 +59,40 @@ getZone db name
                    , soaExpirationLimit    = fromIntegral $ r!Zones.expire
                    , soaMinimumTTL         = fromIntegral $ r!Zones.minTTL
                    }
-           _   -> return Nothing
\ No newline at end of file
+           _   -> return Nothing
+
+putZone :: Database -> DomainName -> SOAFields -> IO ()
+putZone db name soa
+    = transaction db $
+      do old <- getZone db name
+         case old of
+           Just old'
+               -> if soaSerialNumber old' == soaSerialNumber soa - 1 then
+                      -- Succeeded at optimistic locking
+                      updateZone
+                  else
+                      fail "putZone: detected a conflict. please retry it."
+           Nothing
+               -> insertZone
+    where
+      updateZone
+          = DB.update db Zones.zones
+            (\ r -> r!Zones.zone .==. constant (show name))
+            (\ _ -> Zones.ns      << constant (show $ soaMasterNameServer        soa) #
+                    Zones.owner   << constant (show $ soaResponsibleMailbox      soa) #
+                    Zones.serial  << constant (fromIntegral $ soaSerialNumber    soa) #
+                    Zones.refresh << constant (fromIntegral $ soaRefreshInterval soa) #
+                    Zones.retry   << constant (fromIntegral $ soaRetryInterval   soa) #
+                    Zones.expire  << constant (fromIntegral $ soaExpirationLimit soa) #
+                    Zones.minTTL  << constant (fromIntegral $ soaMinimumTTL      soa) )
+
+      insertZone
+          = DB.insert db Zones.zones
+            ( Zones.zone    <<- show name                             #
+              Zones.ns      <<- show (soaMasterNameServer        soa) #
+              Zones.owner   <<- show (soaResponsibleMailbox      soa) #
+              Zones.serial  <<- fromIntegral (soaSerialNumber    soa) #
+              Zones.refresh <<- fromIntegral (soaRefreshInterval soa) #
+              Zones.retry   <<- fromIntegral (soaRetryInterval   soa) #
+              Zones.expire  <<- fromIntegral (soaExpirationLimit soa) #
+              Zones.minTTL  <<- fromIntegral (soaMinimumTTL      soa) )