{"id":12523,"date":"2014-12-12T00:00:45","date_gmt":"2014-12-11T15:00:45","guid":{"rendered":"http:\/\/labs.gree.jp\/blog\/?p=12523"},"modified":"2014-12-10T11:41:45","modified_gmt":"2014-12-10T02:41:45","slug":"haskell%e3%81%aepersistent%e3%83%a9%e3%82%a4%e3%83%96%e3%83%a9%e3%83%aa%e3%81%aezookeeper%e3%83%90%e3%83%83%e3%82%af%e3%82%a8%e3%83%b3%e3%83%89%e3%81%ae%e9%96%8b%e7%99%ba","status":"publish","type":"post","link":"https:\/\/labs.gree.jp\/blog\/2014\/12\/12523\/","title":{"rendered":"Haskell\u306ePersistent\u30e9\u30a4\u30d6\u30e9\u30ea\u306eZooKeeper\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u958b\u767a"},"content":{"rendered":"<p>\u3053\u3093\u306b\u3061\u306f\uff01\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u672c\u90e8\u306e\u6a4b\u672c\u3067\u3059\u3002<\/p>\n<p>\u3053\u306e\u30a8\u30f3\u30c8\u30ea\u306f GREE Advent Calendar 2014 12\u65e5\u76ee\u306e\u8a18\u4e8b\u3067\u3059\u3002<\/p>\n<p>\u8aad\u8005\u306e\u307f\u306a\u3055\u307e\u306e\u4e00\u52a9\u3068\u306a\u308b\u77e5\u898b\u304c\u5c11\u3057\u3067\u3082\u63d0\u4f9b\u3067\u304d\u308c\u3070\u5e78\u3044\u3067\u3059\u3002<\/p>\n<h1>\u306f\u3058\u3081\u306b<\/h1>\n<p>Haskell\u306eO\/R\u30de\u30c3\u30d1\u30fc\u3067\u3042\u308bPersistent\u306e<a href=\"https:\/\/github.com\/yesodweb\/persistent\/tree\/master\/persistent-zookeeper\">ZooKeeper\u30d0\u30c3\u30af\u30a8\u30f3\u30c9<\/a>\u3092\u958b\u767a\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>Persistent\u306e\u3044\u3044\u3068\u3053\u308d\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<ol>\n<li>Haskell\u306e\u30c7\u30fc\u30bf\u3068DB\u306e\u30c7\u30fc\u30bf\u306e\u5909\u63db\u304c\u81ea\u52d5\uff08O\/R\u30de\u30c3\u30d1\u306a\u306e\u3067\u5f53\u305f\u308a\u524d\u3067\u3059\u306d\u3002\uff09<\/li>\n<li>\u578b\u5b89\u5168\u306b\u52a0\u3048\u3066\u3001\u69cb\u9020\u7684\u306b\u5b89\u5b9a\uff08DB[\"user\"]\u3068\u304b\u6587\u5b57\u5217\u3067DB\u304b\u3089\u5024\u3092\u3068\u3063\u3066\u304f\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\u30af\u30a8\u30ea\u3067\u3082\u540c\u69d8\u3067\u3059\u3002)<\/li>\n<li>\u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u304c\u30d7\u30fc\u30eb\u3055\u308c\u307e\u3059<\/li>\n<li>SQL\u3060\u3051\u3067\u306a\u304fNoSQL\u3082\u6271\u3048\u307e\u3059<\/li>\n<li>\u3088\u304f\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059\uff08Yesod\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306b\u7d44\u307f\u8fbc\u307e\u308c\u3066\u3044\u308b\u3053\u3068\u304c\u5927\u304d\u3044\u3068\u601d\u3044\u307e\u3059\u3002)<\/li>\n<\/ol>\n<p>\u958b\u767a\u306e\u52d5\u6a5f\u306f\u3001\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<p>Gree\u3067\u306fKVS(Flare)\u306e\u30af\u30e9\u30b9\u30bf\u30de\u30cd\u30fc\u30b8\u30e1\u30f3\u30c8\u306e\u305f\u3081ZooKeeper\u3092\u4f7f\u3063\u3066\u3044\u307e\u3059\u3002<br \/>\n\u4e0a\u8a18\u30de\u30cd\u30fc\u30b8\u30e1\u30f3\u30c8\u30b7\u30b9\u30c6\u30e0\u306f\u30e6\u30fc\u30b6\u5411\u3051api-server\uff08Yesod+Persistent\uff09\u3092\u3082\u3063\u3066\u3044\u307e\u3059\u3002<br \/>\napi-server\u306ePersistent\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306fSQLite\u3067\u3057\u305f\u3002<br \/>\n\u5197\u9577\u69cb\u6210\u3092\u3068\u308b\u305f\u3081\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3092MySQL\u3084MongoDB\u3092\u65b0\u3057\u304f\u7acb\u3066\u3066\u3082\u3088\u304b\u3063\u305f\u306e\u3067\u3059\u304c\u3001<br \/>\nKVS(Flare)\u4ee5\u5916\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5225\u306b\u7ba1\u7406\u3057\u305f\u304f\u306a\u304b\u3063\u305f\u305f\u3081\u3001Persistent\u306eZooKeeper\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3092\u958b\u767a\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>\u958b\u767a\u306b\u3042\u305f\u308a\u3001<br \/>\n<a href=\"https:\/\/github.com\/yesodweb\/persistent\">https:\/\/github.com\/yesodweb\/persistent<\/a><br \/>\n\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u306f\u3082\u3061\u308d\u3093\u306e\u3053\u3068Redis\u30d0\u30c3\u30af\u30a8\u30f3\u30c9<br \/>\n<a href=\"https:\/\/github.com\/yesodweb\/persistent\/tree\/master\/persistent-redis\">https:\/\/github.com\/yesodweb\/persistent\/tree\/master\/persistent-redis<\/a><br \/>\n(\u4f5c\u8005\u306f<a href=\"http:\/\/www.amazon.co.jp\/dp\/B00G9307YQ\/\">Haskell Financial Data Modeling and Predictive Analytics<\/a>\u306e\u672c\u306e\u65b9\u3067\u3059\u3002)<br \/>\n\u3092\u53c2\u8003\u306b\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>\u958b\u767a\u306f\u624b\u63a2\u308a\u72b6\u614b\u3067\u3057\u305f\u304c\u3001\u305d\u306e\u7d4c\u904e\u3092\u3054\u5831\u544a\u3057\u307e\u3059\u3002<\/p>\n<h1>ZooKeeper\u306b\u7e4b\u3052\u307e\u3057\u3087\u3046(PersistConfig\u3092\u5b9f\u88c5)<\/h1>\n<p>ZooKeeper\u306b\u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u3092\u958b\u3044\u3066\u3001\u305d\u306e\u30cf\u30f3\u30c9\u30eb\u3092\u5f8c\u306e\u51e6\u7406\u306b\u308f\u305f\u3059\u3060\u3051\u306e\u306f\u305a\u306a\u306e\u3067\u3059\u304c\u3001\u3064\u306a\u3052\u308b\u3068\u3053\u308d\u304c\u96e3\u3057\u3044\uff08\u308f\u304b\u308a\u306b\u304f\u3044\uff09\u3067\u3059\u3002<br \/>\nZooKeeper\u306b\u3064\u306a\u3050\u305f\u3081\u306bPersistConfig\u306e\u5b9f\u88c5\u304c\u5fc5\u9808\u306a\u306e\u3067\u3059\u304c\u3001PersistConfig\u306e\u5b9a\u7fa9\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3001<br \/>\n<a href=\"http:\/\/www.yesodweb.com\/book\/persistent\">Persistent\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/a>\u3084\u30b3\u30fc\u30c9\u3092\u898b\u3066\u307f\u307e\u3057\u305f\u304c\u3001<br \/>\n\u958b\u767a\u5f53\u521d\u306e\u50d5\u306b\u306f\u307e\u3063\u305f\u304f\u610f\u5473\u4e0d\u660e\u3067\u3057\u305f\u3002<\/p>\n<p>\u7279\u306b\u91cd\u8981\u305d\u3046\u306a\"(* -&gt; *) -&gt; * -&gt; *\"\u304c\u308f\u304b\u308a\u307e\u305b\u3093\u3002<br \/>\n\u5b9f\u969b\u306b\u306f\"(ReaderT -&gt; (\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u30cf\u30f3\u30c9\u30eb)) -&gt; \u30e2\u30ca\u30c9 -&gt; \u623b\u308a\u5024\"\u306a\u611f\u3058\u3067\u4f7f\u308f\u308c\u307e\u3059\u3002<br \/>\nHaskell\u306a\u306e\u306b\u5168\u7136\u578b\u306f\u73fe\u308c\u3066\u3053\u306a\u3044\u3067\u3059\u306d\u3002<\/p>\n<pre>\nclass PersistConfig c where\n  type PersistConfigBackend c :: (* -> *) -> * -> *\n  type PersistConfigPool c\n\n  -- | Load the config settings from a 'Value', most likely taken from a YAML\n  -- config file.\n  loadConfig :: Value -> Parser c\n\n  -- | Modify the config settings based on environment variables.\n  applyEnv :: c -> IO c\n  applyEnv = return\n\n  -- | Create a new connection pool based on the given config settings.\n  createPoolConfig :: c -> IO (PersistConfigPool c)\n\n  -- | Run a database action by taking a connection from the pool.\n  runPool :: (MonadBaseControl IO m, MonadIO m)\n    => c\n    -> PersistConfigBackend c m a\n    -> PersistConfigPool c\n    -> m a\n<\/pre>\n<p>\u305d\u3053\u3067\u3001persistent-redis\u306e<a href=\"https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-redis\/Database\/Persist\/Redis\/Config.hs\">\u5b9f\u88c5<\/a>\u3092\u898b\u307e\u3057\u305f\u3002<\/p>\n<div class=\"blog-card\">\n<div class=\"blog-card-body-outer\">\n<div class=\"blog-card-body\">\n<h5 class=\"blog-card-title\">\n\t\t\t\t\t\t\t\t<a href=\"http:\/\/hackage.haskell.org\/package\/hedis-0.6.5\/docs\/src\/Database-Redis-Core.html\">src\/Database\/Redis\/Core.hs<\/a><br \/>\n\t\t\t\t\t\t\t<\/h5>\n<div class=\"blog-card-site-title\">\n\t\t\t\t\t\t\t<a href=\"http:\/\/hackage.haskell.org\"><br \/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thttp:\/\/hackage.haskell.org\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>\u3092\u307f\u308b\u3068\u3069\u3046\u3084\u3089<br \/>\ncreatePoolConfig\u3067PersistConfigPool c\u3068\u306a\u3063\u3066\u3044\u308b\u3068\u3053\u308d\u3092Data.Pool\u306ePool\u578b\u3067\u8fd4\u3057\u3066\u3001<br \/>\nrunPool\u3067Pool\u578b\u306e\u30c7\u30fc\u30bf\u3068DB\u306e\u30a2\u30af\u30b7\u30e7\u30f3(PersistConfigBackend c m a)\u3092\u6e21\u3057\u3066\u7d50\u679c\u3092\u623b\u305b\u3070\u3044\u3044\u3053\u3068\u304c\u5206\u304b\u308a\u307e\u3057\u305f\u3002<br \/>\n\u307b\u3068\u3093\u3069persistent-redis\u306e\u5b9f\u88c5\u3092\u30b3\u30d4\u30da\u3057\u3066<br \/>\n<a href=\"https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-zookeeper\/Database\/Persist\/Zookeeper\/Config.hs\">https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-zookeeper\/Database\/Persist\/Zookeeper\/Config.hs<\/a><br \/>\n\u3092\u4f5c\u308a\u307e\u3057\u305f\u3002Z.connect\u306e\u3068\u3053\u308d\u306fhzk\u30d1\u30c3\u30b1\u30fc\u30b8\u306e<br \/>\n<a href=\"https:\/\/github.com\/dgvncsz0f\/hzk\/blob\/master\/src\/Database\/Zookeeper\/Pool.hs\">https:\/\/github.com\/dgvncsz0f\/hzk\/blob\/master\/src\/Database\/Zookeeper\/Pool.hs<br \/>\n<\/a><br \/>\n\u306econnect\u3067Data.Pool\u306ePool\u578b\u304c\u623b\u308a\u307e\u3059\u3002\u3084\u308a\u305f\u3044\u3053\u3068\u306f\u30b7\u30f3\u30d7\u30eb\u306a\u306e\u3067\u3059\u304c\u3001\u578b\u304c\u5206\u304b\u308a\u306b\u304f\u3044\u3067\u3059\u306d\u3002<\/p>\n<h1>\u3068\u308a\u3042\u3048\u305aPersistStore\u3068PersistUnique\u306e\u30e2\u30c3\u30af\u3092\u3064\u304f\u308a\u307e\u3057\u3087\u3046<\/h1>\n<p>\u578b\u3092\u5408\u308f\u305b\u308b\u306e\u306f\u96e3\u3057\u3044\u3067\u3059\u3057\u3001\u306f\u3058\u3081\u304b\u3089\u5168\u90e8\u4f5c\u308b\u306e\u306f\u5927\u5909\u3067\u3059\u3002<br \/>\n\u5b9a\u7fa9\u3057\u306a\u3044\u3068\u3044\u3051\u306a\u3044\u95a2\u6570\u3082\u591a\u3044\u3057\u3001\u3080\u305a\u304b\u3057\u305d\u3046\u3060\u306a\u3068\u601d\u3063\u3066\u3044\u307e\u3057\u305f\u304c\u3001<br \/>\n\u4ed6\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3092\u898b\u308b\u3068\u3068error\u3068\u304bfail\u3068\u304b\u3067\u5b9f\u88c5\u3055\u308c\u3066\u306a\u3044\u30b3\u30fc\u30c9\u304c\u5165\u3063\u3066\u3044\u307e\u3059\u3002<br \/>\n\u306f\u3058\u3081\u306f\u3068\u308a\u3042\u3048\u305aerror \"not support\"\u3063\u3066\u66f8\u3044\u3066\u3001\u3042\u3068\u3067\u4e2d\u8eab\u3092\u66f8\u304d\u307e\u3057\u305f\u3002<\/p>\n<pre>\ninstance PersistStore Z.Zookeeper where\n  newtype BackendKey Z.Zookeeper = ZooKey { unZooKey :: T.Text }\n    deriving (Show, Read, Eq, Ord, PersistField)\n  insert val = error \"not support\"\n  get key = error \"not support\"\n<\/pre>\n<h1>\u30d3\u30eb\u30c9\u3057\u3066\u3001Yesod\u306b\u7d44\u307f\u8fbc\u3093\u3067\u307f\u307e\u3057\u3087\u3046<\/h1>\n<p>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u5207\u308a\u66ff\u3048\u306f\u3001Yesod\u306e\u30d5\u30a1\u30a4\u30eb\u306eModel.hs\u306e\u30d5\u30a1\u30a4\u30eb\u306e<\/p>\n<pre>\nshare [mkPersist sqlSettings, mkMigrate \"migrateAll\"]\n$(persistFileWith lowerCaseSettings \"config\/models\")\n<\/pre>\n<p>\u3068\u306a\u3063\u3066\u3044\u308b\u3068\u3053\u308d\u3092<\/p>\n<pre>\nlet mongoSettings = (mkPersistSettings (ConT ''Z.Zookeeper))\nin share [mkPersist mongoSettings]\n$(persistFileWith upperCaseSettings \"config\/models\")\n<\/pre>\n<p>\u306b\u3057\u307e\u3059\u3002<br \/>\nConT\u306fTemplate-Haskell\u306e\u3082\u306e\u3089\u3057\u3044\u3067\u3059\u304c\u3001\u306a\u305c\u5fc5\u8981\u306a\u306e\u304b\u3088\u304f\u5206\u304b\u3063\u3066\u307e\u305b\u3093\u3002<\/p>\n<p>\u6b21\u306b\u3001<\/p>\n<pre>\ninstance YesodPersist App where\n    type YesodPersistBackend App = SqlPersistT\n    runDB = defaultRunDB persistConfig connPool\n<\/pre>\n<p>\u3068\u306a\u3063\u3066\u3044\u308b\u3068\u3053\u308d\u3092<\/p>\n<pre>\ninstance YesodPersist App where\n    type YesodPersistBackend App = Z.Zookeeper\n    runDB = defaultRunDB persistConfig connPool\n<\/pre>\n<p>\u306b\u3057\u307e\u3059\u3002\u3053\u308c\u3067\u30d3\u30eb\u30c9\u306f\u901a\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002\uff08\u307e\u3060\u5b9f\u88c5\u3057\u3066\u306a\u3044\u306e\u3067\u52d5\u304b\u306a\u3044\u3067\u3059\u3002\uff09<\/p>\n<h1>PersistStore\u3068PersistUnique\u306e\u5b9f\u88c5<\/h1>\n<p>get\u3001insert\u3001delete\u3068\u3044\u3063\u305f\u64cd\u4f5c\u306bPersistStore\u306e\u5b9f\u88c5\u304c\u5fc5\u8981\u3067\u3059\u3002<br \/>\nPersistStore\u306e\u5b9a\u7fa9\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u304c\u3001<br \/>\n\u4e00\u898b\u3059\u308b\u3068get\u3084insert\u306e\u4e2d\u306e\u30e2\u30ca\u30c9\u3067\u30c6\u30fc\u30d6\u30eb\u540d\u3092\u5f15\u304f\u65b9\u6cd5\u304c\u308f\u304b\u308a\u307e\u305b\u3093\u3002<\/p>\n<pre>\nclass\n  ( Show (BackendKey backend), Read (BackendKey backend)\n  , Eq (BackendKey backend), Ord (BackendKey backend)\n  , PersistField (BackendKey backend), A.ToJSON (BackendKey backend), A.FromJSON (BackendKey backend)\n  ) => PersistStore backend where\n    data BackendKey backend\n\n    -- | Get a record by identifier, if available.\n    get :: (MonadIO m, backend ~ PersistEntityBackend val, PersistEntity val)\n        => Key val -> ReaderT backend m (Maybe val)\n\n    -- | Create a new record in the database, returning an automatically created\n    -- key (in SQL an auto-increment id).\n    insert :: (MonadIO m, backend ~ PersistEntityBackend val, PersistEntity val)\n           => val -> ReaderT backend m (Key val)\n<\/pre>\n<p>PersistEntity\u304b\u3089\u30c6\u30fc\u30d6\u30eb\u540d\u3092\u5f15\u304f\u65b9\u6cd5\u3082persistent-redis\u304b\u3089\u501f\u7528\u3057\u307e\u3057\u305f\u3002<br \/>\n\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<p>PersistEntity val\u304b\u3089\u30c6\u30fc\u30d6\u30eb\u540d\u3092\u5f15\u304f\u65b9\u6cd5\u3067\u3059\u3002<\/p>\n<pre>\ntoEntityString :: PersistEntity val => val -> Text\ntoEntityString val = (unDBName . entityDB . entityDef . Just) val\n<\/pre>\n<p>PersistEntity val =&gt; Key val\u304b\u3089\u30c6\u30fc\u30d6\u30eb\u540d\u3092\u5f15\u304f\u65b9\u6cd5\u3067\u3059\u3002<br \/>\ndummyFromKey\u3092\u4f7f\u3044\u307e\u3059\u304c\u3001\u5b9f\u969b\u306b\u306fval\u306e\u3068\u3053\u308d\u306f\u8a55\u4fa1\u3055\u308c\u306a\u3044\u306e\u3067\u3001\u3053\u308c\u3067\u30c6\u30fc\u30d6\u30eb\u306e\u540d\u524d\u3092\u5f15\u304f\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<pre>\ndummyFromKey :: Key v -> v\ndummyFromKey _ = error \"do not eval this\"\ntoEntityStringFromKey :: PersistEntity val => Key val -> Text\ntoEntityStringFromKey key = toEntityString $ dummyFromKey key\n<\/pre>\n<p>\u6b21\u306bZooKeeper\u306b\u30c7\u30fc\u30bf\u3092\u3044\u308c\u308b\u305f\u3081\u306e\u30ad\u30fc\u3092\u4f55\u306b\u3059\u308b\u306e\u304b\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<br \/>\nPersistStore\u306einsert\u306f\u540c\u3058\u30ad\u30fc\u306e\u91cd\u8907\u3092\u8a31\u3057\u307e\u3059\u304c\u3001PersistUnique\u306einsertBy\u3067\u306f\u8a31\u3057\u307e\u305b\u3093\u3002<\/p>\n<p>KVS\u306a\u306e\u3067\u59a5\u5354\u304c\u5fc5\u8981\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<ol>\n<li>\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u306b\u30d7\u30e9\u30a4\u30de\u30ea\u30ad\u30fc\u304c\u3042\u308b\u5834\u5408\u3068\u7121\u3044\u5834\u5408<\/li>\n<li>\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u306b\u30e6\u30cb\u30fc\u30af\u306a\u30ad\u30fc\u304c\u3042\u308b\u5834\u5408\u3068\u7121\u3044\u5834\u5408<\/lib>\n<\/ol>\n<p>\u3053\u308c\u3089\u306e\u30b1\u30fc\u30b9\u3092\u8003\u3048\u3066\u3001\u4e0b\u8a18\u306e\u8868\u306b\u3057\u305f\u304c\u3063\u3066\u30ad\u30fc\u3092\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u304b\u3089\u53d6\u308a\u51fa\u3057\u3066ZooKeeper\u306e\u30ad\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc\u6709<\/th>\n<th>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc\u7121<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u30d7\u30e9\u30a4\u30de\u30ea\u30fc\u30ad\u30fc\u6709<\/td>\n<td>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc<\/td>\n<td>\u30d7\u30e9\u30a4\u30de\u30ea\u30fc\u30ad\u30fc<\/td>\n<\/tr>\n<tr>\n<td>\u30d7\u30e9\u30a4\u30de\u30ea\u30fc\u30ad\u30fc\u7121<\/td>\n<td>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc<\/td>\n<td>\u9023\u756a\u30ad\u30fc\uff08\u756a\u53f7\u306fZooKeeper\u304c\u767a\u884c\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h1>PersistQuery\u306e\u5b9f\u88c5(\u6383\u9664\u306f\u3069\u3046\u3057\u307e\u3057\u3087\u3046\u304b)<\/h1>\n<p>PersistStore\u306b\u306f\u30ad\u30fc\u3092\u5217\u6319\u3059\u308b\u6a5f\u80fd\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u3053\u306e\u307e\u307e\u3067\u306f\u671f\u9650\u5207\u308c\u306e\u30c7\u30fc\u30bf\u3084\u3044\u3089\u306a\u304f\u306a\u3063\u305f\u30c7\u30fc\u30bf\u304c\u3044\u3064\u307e\u3067\u3082\u6b8b\u3063\u3066\u3057\u307e\u3044\u307e\u3059\u3002<br \/>\n\u30ad\u30fc\u3092\u30ea\u30b9\u30c8\u30a2\u30c3\u30d7\u3057\u3066\u6383\u9664\u3059\u308b\u306b\u306fPersistQuery\u306e\u5b9f\u88c5\u304c\u5fc5\u8981\u3067\u3059\u3002<br \/>\nPersistQuery\u306b\u306fFilter\uff08\u6761\u4ef6\u6587\u307f\u305f\u3044\u306a\u3082\u306e\uff09\u3068SelectOpt(Orderby,Limit\u3068\u3044\u3063\u305f\u3082\u306e)\u3068\u3044\u3046\u578b\u5b89\u5168\u306awhere\u6587\u304c\u3042\u308a\u307e\u3059\u3002<br \/>\n\u524a\u9664\u3067\u306fFilter\u3060\u3051\u5b9f\u88c5\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304c\u3001\u6b8b\u5ff5\u306a\u304c\u3089ZooKeeper\u81ea\u4f53\u306b\u306f\u307e\u3063\u305f\u304f\u6761\u4ef6\u6587\u76f8\u5f53\u306e\u6a5f\u80fd\u304c\u306a\u304f\u3001persistent-redis\u306b\u3082\u306a\u3044\u306e\u3067\u56f0\u308a\u307e\u3057\u305f\u3002<\/p>\n<p>\u3057\u304b\u3057\u3001Filter\u306e\u5024\u304b\u3089SQL\u306e\u30af\u30a8\u30ea\u3092\u3064\u304f\u308b\u95a2\u6570\u304c\u3042\u3063\u305f\u306e\u3067\u3001<br \/>\n<a href=\"https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent\/Database\/Persist\/Sql\/Orphan\/PersistQuery.hs#L239\">https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent\/Database\/Persist\/Sql\/Orphan\/PersistQuery.hs#L239<\/a><br \/>\n\u305d\u308c\u3092\u3082\u3068\u306b\u5024\u3092\u30d5\u30a3\u30eb\u30bf\u3067\u304d\u308b\u95a2\u6570\uff08filterClause\uff09\u3092\u4f5c\u308a\u307e\u3057\u305f\u3002<br \/>\n<a href=\"https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-zookeeper\/Database\/Persist\/Zookeeper\/Query.hs#L118\">https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-zookeeper\/Database\/Persist\/Zookeeper\/Query.hs#L118<br \/>\n<\/a><br \/>\n\u3053\u308c\u3067\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u524a\u9664(deleteWhere)\u304c\u66f8\u3051\u307e\u3057\u305f\u3002<\/p>\n<pre>\n  deleteWhere filterList = do\n    (str::[String]) <- execZookeeper $ \\zk -> do\n      zGetChildren zk (filter2path filterList)\n    loop str\n    where\n      loop [] = return ()\n      loop (x:xs) = do\n        let key = txtToKey x\n        case filterList of\n          [] -> delete key\n          _ -> del key\n        loop xs\n      del key = do\n        va <- get key\n        case va of\n          Nothing -> return ()\n          Just v -> do\n            let (chk,_,_) = filterClause v filterList\n            if chk\n              then delete key\n              else return ()\n<\/pre>\n<h1>persistent-test\u3078\u306e\u5bfe\u5fdc\uff08\u30c6\u30b9\u30c8\u306f\u5145\u5206\u306a\u306e\uff1f\uff09<\/h1>\n<p><a href=\"https:\/\/github.com\/yesodweb\/persistent\/tree\/master\/persistent-test\">persistent-test<\/a>\u3067\u4ed6\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068\u306e\u4e92\u63db\u6027\u304c\u78ba\u4fdd\u3055\u308c\u3066\u3044\u307e\u3059\u3002<br \/>\nKVS\u3067\u3053\u306e\u30c6\u30b9\u30c8\u3092\u884c\u3063\u3066\u3044\u308b\u306e\u306fpersistent-mongoDB\u3060\u3051\u3067\u3057\u305f\u306e\u3067\u3001persistent-mongoDB\u306e\u30c6\u30b9\u30c8\u3092\u5143\u306bpersistent-test\u306b\u5bfe\u5fdc\u3057\u307e\u3057\u305f\u3002<br \/>\n\u306f\u3058\u3081\u306f2\/60\u500b\u3057\u304b\u901a\u3089\u305a\u4ee5\u4e0b\u306e\u554f\u984c\u304c\u3042\u308a\u307e\u3057\u305f\u3002<\/p>\n<ol>\n<li>insertKey\uff08\u30d7\u30e9\u30a4\u30de\u30ea\u30ad\u30fc\u304cID\u3067\u306a\u3044\u30b1\u30fc\u30b9\uff09\u306e\u30d0\u30b0<\/li>\n<li>deleteWhere\u306e\u30d0\u30b0<\/li>\n<li>SelectOpt\u306e\u672a\u5b9f\u88c5<\/li>\n<li>id\u306e\u554f\u984c<\/li>\n<\/ol>\n<p>1,insertKey\uff08\u30d7\u30e9\u30a4\u30de\u30ea\u30ad\u30fc\u304cID\u3067\u306a\u3044\u30b1\u30fc\u30b9\uff09\u306e\u30d0\u30b0\u306f\u3001<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc\u6709<\/th>\n<th>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc\u7121<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u30d7\u30e9\u30a4\u30de\u30ea\u30fc\u30ad\u30fc\u6709<\/td>\n<td>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc<\/td>\n<td>\u9023\u756a\u30ad\u30fc\uff08\u3053\u3053\u9593\u9055\u3044\uff09<\/td>\n<\/tr>\n<tr>\n<td>\u30d7\u30e9\u30a4\u30de\u30ea\u30fc\u30ad\u30fc\u7121<\/td>\n<td>\u30e6\u30cb\u30fc\u30af\u30ad\u30fc<\/td>\n<td>\u9023\u756a\u30ad\u30fc<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u3068\u3064\u304f\u3063\u3066\u3044\u305f\u3053\u3068\u304c\u554f\u984c\u3067\u3057\u305f\u3002\u30c6\u30b9\u30c8\u3067\u898b\u3064\u304b\u3063\u3066\u3088\u304b\u3063\u305f\u3067\u3059\u3002<\/p>\n<p>2,deleteWhere\u306e\u30d0\u30b0\u306f\u3001\u30c6\u30fc\u30d6\u30eb\u304c\u306a\u3044\u3068\u304d\u306b\u5b9f\u884c\u3059\u308b\u3068\u4f8b\u5916\u304c\u98db\u3076\u3088\u3046\u306b\u306a\u3063\u3066\u3044\u305f\u3053\u3068\u304c\u554f\u984c\u3067\u3057\u305f\u3002\u4ed6\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306b\u5408\u308f\u305b\u3066\u4f8b\u5916\u304c\u51fa\u306a\u3044\u3088\u3046\u306b\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>3,SelectOpt\u306fselect\u6587\u306ewhere\u306eOrderby\u3084Limit\u306b\u5bfe\u5fdc\u3057\u307e\u3059\u3002\u30c6\u30b9\u30c8\u304b\u3089\u9664\u3044\u3066\u3082\u3088\u304b\u3063\u305f\u306e\u3067\u3059\u304c\u3001SelectOpt\u306e\u5b9f\u88c5\u3092\u3057\u307e\u3057\u305f\u3002\u5024\u306b\u3057\u305f\u304c\u3063\u3066\u7d50\u679c\u3092\u30bd\u30fc\u30c8\u3059\u308b\u95a2\u6570\u3092\u7528\u610f\u3057\u307e\u3057\u305f\u3002\u5b9f\u88c5\u304c\u30ea\u30b9\u30c8\u306e\u30ea\u30b9\u30c8\u3092\u30bd\u30fc\u30c8\u3057\u3066\u3044\u308b\u306e\u306f\u8907\u6570\u306eOrderby\u306b\u5bfe\u5fdc\u3059\u308b\u305f\u3081\u3067\u3059\u3002<br \/>\n<a href=\"https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-zookeeper\/Database\/Persist\/Zookeeper\/Query.hs#L247\">https:\/\/github.com\/yesodweb\/persistent\/blob\/master\/persistent-zookeeper\/Database\/Persist\/Zookeeper\/Query.hs#L247<\/a><\/p>\n<p>4,id\u306e\u554f\u984c\u306fSQL\u306eauto increment\u306eid\u3084mongoDB\u306eobjectID\u306b\u76f8\u5f53\u3059\u308b\u3082\u306e\u304cZooKeeper\u306b\u306f\u306a\u3044\u3053\u3068\u304c\u539f\u56e0\u3067\u3059\u3002\u5b9f\u88c5\u3067\u304d\u306a\u3044\u306e\u3067\u30c6\u30b9\u30c8\u3092\u30b9\u30ad\u30c3\u30d7\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>\u7121\u4e8b\u3001\u624b\u5143\u3067persistent-test\u3092\u30d1\u30b9\u3057\u307e\u3057\u305f\u3002<\/p>\n<h2>Travis CI<\/h2>\n<p>\u3057\u304b\u3057\u3001Travis CI\u3067persistent-test\u306f\u307b\u3068\u3093\u3069Fail\u3057\u307e\u3057\u305f\u3002<br \/>\n\u539f\u56e0\u306f\u3001Travis CI\u306eprecise\u3067\u7acb\u3061\u4e0a\u3052\u308bZooKeeper\u306emax client\u306e\u8a2d\u5b9a\u304c10\u3060\u3063\u305f\u3053\u3068\u3068libzookeeper\u306e\u30d0\u30b0\u3067\u3057\u305f\u3002<\/p>\n<p>precise\u3067\u5165\u308blibzookeeper\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304c3.3.5\u306a\u306e\u3067\u3059\u304c\u3001create(libzookeeper\u306eAPI)\u3067\u623b\u3063\u3066\u304f\u308b\u30d1\u30b9\u306b\u6df1\u523b\u306a\u30d0\u30b0\u304c\u3042\u308a\u307e\u3059\u3002\u3053\u308c\u3067\u3059\u3002<br \/>\n<a href=\"https:\/\/issues.apache.org\/jira\/browse\/ZOOKEEPER-1027\">https:\/\/issues.apache.org\/jira\/browse\/ZOOKEEPER-1027<\/a><br \/>\n\u4f5c\u3063\u305f\u30ce\u30fc\u30c9\u306e\u30d1\u30b9\u304c\u623b\u3063\u3066\u3053\u306a\u3044\u554f\u984c\u3067\u3059\u3002create\u3057\u305f\u3068\u304d\u306e\u30ad\u30fc\u304c\u95a2\u6570\u304b\u3089\u623b\u3063\u3066\u304d\u307e\u305b\u3093\u3002\u7279\u306b\u9023\u756a\u306e\u30ad\u30fc\u3092\u4f5c\u3063\u305f\u5834\u5408\u306b\u3069\u3053\u306e\u30ad\u30fc\u306b\u5165\u3063\u305f\u304b\u5206\u304b\u308a\u307e\u305b\u3093\u3002<br \/>\n\u3069\u3046\u3057\u3088\u3046\u3082\u306a\u3044\u306e\u3067\u3001ppa\u304b\u3089libzookeeper\u306e3.4.5\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u3088\u3046\u306b\u76f4\u3057\u307e\u3057\u305f\u3002<\/p>\n<h1>\u6700\u5f8c\u306b<\/h1>\n<p>\u7121\u4e8b\u306bZooKeeper\u3092Persistent\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306b\u3067\u304d\u3001\u672c\u5bb6\u306b\u30de\u30fc\u30b8\u3055\u308c\u307e\u3057\u305f\u3002<br \/>\n\uff08persistent-test\u3092ZooKeeper\u7528\u306b\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3057\u305f\u306e\u3067\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u304c\u3084\u308a\u3084\u3059\u304f\u306a\u308b\u305f\u3081\u3001\u3046\u308c\u3057\u3044\u3067\u3059\u3002\uff09<br \/>\n\u672c\u958b\u767a\u306b\u3042\u305f\u308a\u7d20\u6674\u3089\u3057\u3044\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u63d0\u4f9b\u3057\u3066\u304f\u308c\u305fhzk\u3001persistent\u3001persistent-redis\u3001persistent-mongoDB\u306e\u958b\u767a\u8005\u306e\u307f\u306a\u3055\u3093\u306b\u611f\u8b1d\u3057\u307e\u3059\u3002<\/p>\n<p>\u3068\u3053\u308d\u3067\u3001git-annex\u306fhaskell\u3067\u304b\u304b\u308c\u3066\u3044\u308b\u306e\u3067\u3059\u304c\u3001\u62d9\u4f5c\u306es3\u306emultipart upload\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u307e\u3057\u305f\u3002<br \/>\n\u3053\u306e\u8a71\u306f\u5225\u306e\u6a5f\u4f1a\u306b\u3067\u304d\u305f\u3089\u3044\u3044\u3067\u3059\u3002<\/p>\n<p>Haskell\u306b\u8208\u5473\u3092\u3082\u3063\u3066\u3044\u305f\u3060\u3051\u308b\u3068\u5e78\u3044\u3067\u3059\u3002<\/p>\n<p>\u660e\u65e5\u306f\u5c71\u672c\u3055\u3093\u306b\u3088\u308b\u30b0\u30ea\u30fc\u306eQA(\u54c1\u8cea\u4fdd\u8a3c)\u3068\u305d\u306e\u80cc\u666f\u306e\u6280\u8853\u306e\u8a18\u4e8b\u3067\u3059\u3002\u304a\u697d\u3057\u307f\u306b\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3053\u3093\u306b\u3061\u306f\uff01\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u672c\u90e8\u306e\u6a4b\u672c\u3067\u3059\u3002 \u3053\u306e\u30a8\u30f3\u30c8\u30ea\u306f GREE Advent Calendar 2014 12\u65e5\u76ee\u306e\u8a18\u4e8b\u3067\u3059\u3002 \u8aad\u8005\u306e\u307f\u306a\u3055\u307e\u306e\u4e00\u52a9\u3068\u306a\u308b\u77e5\u898b\u304c\u5c11\u3057\u3067\u3082\u63d0\u4f9b\u3067\u304d\u308c\u3070\u5e78\u3044\u3067\u3059\u3002 \u306f\u3058\u3081\u306b Has [&hellip;]<\/p>\n","protected":false},"author":134,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[54],"class_list":["post-12523","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-advent-calendar"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts\/12523","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/users\/134"}],"replies":[{"embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/comments?post=12523"}],"version-history":[{"count":3,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts\/12523\/revisions"}],"predecessor-version":[{"id":12612,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts\/12523\/revisions\/12612"}],"wp:attachment":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/media?parent=12523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/categories?post=12523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/tags?post=12523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}