blob: 6d0c48b476adce7d984a93ef3ef3c22f519415c8 [file] [log] [blame]
Alexander Afanasyeva199f972013-01-02 19:37:26 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012-2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
20 */
21
22#include "action-log.h"
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080023#include <action-item.pb.h>
Alexander Afanasyeva199f972013-01-02 19:37:26 -080024
25using namespace boost;
26using namespace std;
27
28ActionLog::ActionLog (const std::string &path, const std::string &localName)
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080029 : SyncLog (path, localName)
Alexander Afanasyeva199f972013-01-02 19:37:26 -080030{
31}
32
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080033tuple<sqlite3_int64, sqlite3_int64, sqlite3_int64>
34ActionLog::GetExistingRecord (const std::string &filename)
35{
36 // check if something already exists
37 sqlite3_stmt *stmt;
38 int res = sqlite3_prepare_v2 (m_db, "SELECT version,device_id,seq_no FROM ActionLog WHERE filename=? ORDER BY version DESC,device_id DESC LIMIT 1", -1, &stmt, 0);
39
40 if (res != SQLITE_OK)
41 {
42 BOOST_THROW_EXCEPTION (Error::Db ()
43 << errmsg_info_str ("Some error with AddActionUpdate"));
44 }
45
46 sqlite3_bind_text (stmt, 1, filename.c_str (), filename.size (), SQLITE_STATIC);
47 if (sqlite3_step (stmt) == SQLITE_ROW)
48 {
49 // with parent with version number + 1
50 sqlite3_int64 version = sqlite3_column_int64 (stmt, 0) + 1;
51 sqlite3_int64 parent_device_id = sqlite3_column_int64 (stmt, 1);
52 sqlite3_int64 parent_seq_no = sqlite3_column_int64 (stmt, 0);
53
54 sqlite3_finalize (stmt);
55 return make_tuple (version, parent_device_id, parent_seq_no);
56 }
57
58 sqlite3_finalize (stmt);
59 return make_tuple ((sqlite3_int64)0, (sqlite3_int64)-1, (sqlite3_int64)-1);
60}
61
Alexander Afanasyeva199f972013-01-02 19:37:26 -080062// local add action. remote action is extracted from content object
63void
64ActionLog::AddActionUpdate (const std::string &filename,
65 const Hash &hash,
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080066 time_t atime, time_t mtime, time_t ctime,
Alexander Afanasyeva199f972013-01-02 19:37:26 -080067 int mode)
68{
69 int res = sqlite3_exec (m_db, "BEGIN TRANSACTION;", 0,0,0);
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080070
71 sqlite3_int64 seq_no = GetNextLocalSeqNo ();
72 sqlite3_int64 version = 0;
73 sqlite3_int64 parent_device_id = -1;
74 sqlite3_int64 parent_seq_no = -1;
Alexander Afanasyeva199f972013-01-02 19:37:26 -080075
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080076 sqlite3_int64 action_time = time (0);
77
78 tie (version, parent_device_id, parent_seq_no) = GetExistingRecord (filename);
79
80 sqlite3_stmt *stmt;
81 sqlite3_prepare_v2 (m_db, "INSERT INTO ActionLog "
82 "(device_id, seq_no, action, filename, version, action_timestamp, "
83 "file_hash, file_atime, file_mtime, file_ctime, file_chmod, "
84 "parent_device_id, parent_seq_no) "
85 "VALUES (?, ?, ?, ?, ?, datetime(?, 'unixepoch'),"
86 " ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?,"
87 " ?, ?)", -1, &stmt, 0);
Alexander Afanasyeva199f972013-01-02 19:37:26 -080088
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080089 sqlite3_bind_int64 (stmt, 1, m_localDeviceId);
90 sqlite3_bind_int64 (stmt, 2, seq_no);
91 sqlite3_bind_int (stmt, 3, 0);
92 sqlite3_bind_text (stmt, 4, filename.c_str (), filename.size (), SQLITE_TRANSIENT);
93 sqlite3_bind_blob (stmt, 5, hash.GetHash (), hash.GetHashBytes (), SQLITE_TRANSIENT);
Alexander Afanasyeva199f972013-01-02 19:37:26 -080094
Alexander Afanasyev433ecda2013-01-02 22:13:45 -080095 sqlite3_bind_int64 (stmt, 6, action_time);
96
97 sqlite3_bind_int64 (stmt, 7, atime);
98 sqlite3_bind_int64 (stmt, 8, mtime);
99 sqlite3_bind_int64 (stmt, 9, ctime);
100 sqlite3_bind_int (stmt, 10, mode);
Alexander Afanasyeva199f972013-01-02 19:37:26 -0800101
Alexander Afanasyev433ecda2013-01-02 22:13:45 -0800102 if (parent_device_id > 0 && parent_seq_no > 0)
103 {
104 sqlite3_bind_int64 (stmt, 11, parent_device_id);
105 sqlite3_bind_int64 (stmt, 12, parent_seq_no);
106 }
107 else
108 {
109 sqlite3_bind_null (stmt, 11);
110 sqlite3_bind_null (stmt, 12);
111 }
112
113 sqlite3_step (stmt);
Alexander Afanasyeva199f972013-01-02 19:37:26 -0800114
Alexander Afanasyev433ecda2013-01-02 22:13:45 -0800115 // missing part: creating ContentObject for the action !!!
116
117 ActionItem item;
118 item.set_action (ActionItem::UPDATE);
119 item.set_filename (filename);
120 item.set_version (version);
121 item.set_timestamp (action_time);
122 item.set_file_hash (hash.GetHash (), hash.GetHashBytes ());
123 // item
124
125 sqlite3_finalize (stmt);
126
Alexander Afanasyeva199f972013-01-02 19:37:26 -0800127 res += sqlite3_exec (m_db, "END TRANSACTION;", 0,0,0);
128}
129
130void
131ActionLog::AddActionMove (const std::string &oldFile, const std::string &newFile)
132{
133}
134
135void
136ActionLog::AddActionDelete (const std::string &filename)
137{
138}