diff --git a/.travis.yml b/.travis.yml index 53b6237..0538bea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ matrix: script: - ci/script-rust.sh - language: rust - rust: 1.32.0 + rust: 1.33.0 script: - ci/script-rust.sh - language: node_js diff --git a/Cargo.lock b/Cargo.lock index 16617f5..c6ba5b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,6 +432,16 @@ name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" version = "1.0.7" @@ -700,7 +710,7 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.11.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -892,7 +902,7 @@ dependencies = [ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rusqlite 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rusqlite 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -940,7 +950,7 @@ dependencies = [ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rusqlite 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rusqlite 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1508,12 +1518,15 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libsqlite3-sys 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fallible-streaming-iterator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2292,6 +2305,8 @@ dependencies = [ "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +"checksum fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +"checksum fallible-streaming-iterator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" "checksum flate2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f87e68aa82b2de08a6e037f1385455759df6e445a8df5e005b4297191dbf18aa" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" @@ -2321,7 +2336,7 @@ dependencies = [ "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "a844cabbd5a77e60403a58af576f0a1baa83c3dd2670be63e615bd24fc58b82d" "checksum libpasta 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31a3bd8a4714af6f88d2cd850b016ad4567770f88fa3cf0571ec197591362f99" -"checksum libsqlite3-sys 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3567bc1a0c84e2c0d71eeb4a1f08451babf7843babd733158777d9c686dad9f3" +"checksum libsqlite3-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e310445ab028c374b9efaaed4b7a52a14e3b8ad5a1351b4bbd46dec03ffce717" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" @@ -2398,7 +2413,7 @@ dependencies = [ "checksum reqwest 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)" = "e57803405f8ea0eb041c1567dac36127e0c8caa1251c843cb03d43fd767b3d50" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37473170aedbe66ffa3ad3726939ba677d83c646ad4fd99e5b4bc38712f45ec" -"checksum rusqlite 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6381ddfe91dbb659b4b132168da15985bc84162378cf4fcdc4eb99c857d063e2" +"checksum rusqlite 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "700720c977deb8b91c9d881dcbe3309c254d414078ca3856ea6647e569be3b66" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" diff --git a/Cargo.toml b/Cargo.toml index 3e62952..3ef875b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ parking_lot = { version = "0.8", features = [] } reffers = "0.5.1" regex = "1.0" ring = "0.14.6" -rusqlite = "0.16" +rusqlite = "0.18" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smallvec = "0.6" diff --git a/db/Cargo.toml b/db/Cargo.toml index 8528606..123d6ef 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -28,7 +28,7 @@ openssl = "0.10" parking_lot = { version = "0.7", features = [] } protobuf = "2.0" regex = "1.0" -rusqlite = "0.16" +rusqlite = "0.18" smallvec = "0.6" tempdir = "0.3" time = "0.1" diff --git a/db/auth.rs b/db/auth.rs index 0907046..bacfcb9 100644 --- a/db/auth.rs +++ b/db/auth.rs @@ -347,18 +347,17 @@ impl State { user "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let id = row.get_checked(0)?; - let name: String = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let id = row.get(0)?; + let name: String = row.get(1)?; state.users_by_id.insert(id, User { id, username: name.clone(), - flags: row.get_checked(2)?, - password_hash: row.get_checked(3)?, - password_id: row.get_checked(4)?, - password_failure_count: row.get_checked(5)?, - unix_uid: row.get_checked(6)?, + flags: row.get(2)?, + password_hash: row.get(3)?, + password_id: row.get(4)?, + password_failure_count: row.get(5)?, + unix_uid: row.get(6)?, dirty: false, }); state.users_by_name.insert(name, id); @@ -693,39 +692,35 @@ fn lookup_session(conn: &Connection, hash: &SessionHash) -> Result bail!("no such session"), - Some(Err(e)) => return Err(e.into()), - Some(Ok(r)) => r, - }; - let creation_addr: FromSqlIpAddr = row.get_checked(8)?; - let revocation_addr: FromSqlIpAddr = row.get_checked(11)?; - let last_use_addr: FromSqlIpAddr = row.get_checked(16)?; + let row = rows.next()?.ok_or_else(|| format_err!("no such session"))?; + let creation_addr: FromSqlIpAddr = row.get(8)?; + let revocation_addr: FromSqlIpAddr = row.get(11)?; + let last_use_addr: FromSqlIpAddr = row.get(16)?; Ok(Session { - user_id: row.get_checked(0)?, - seed: row.get_checked(1)?, - flags: row.get_checked(2)?, - domain: row.get_checked(3)?, - description: row.get_checked(4)?, - creation_password_id: row.get_checked(5)?, + user_id: row.get(0)?, + seed: row.get(1)?, + flags: row.get(2)?, + domain: row.get(3)?, + description: row.get(4)?, + creation_password_id: row.get(5)?, creation: Request { - when_sec: row.get_checked(6)?, - user_agent: row.get_checked(7)?, + when_sec: row.get(6)?, + user_agent: row.get(7)?, addr: creation_addr.0, }, revocation: Request { - when_sec: row.get_checked(9)?, - user_agent: row.get_checked(10)?, + when_sec: row.get(9)?, + user_agent: row.get(10)?, addr: revocation_addr.0, }, - revocation_reason: row.get_checked(12)?, - revocation_reason_detail: row.get_checked(13)?, + revocation_reason: row.get(12)?, + revocation_reason_detail: row.get(13)?, last_use: Request { - when_sec: row.get_checked(14)?, - user_agent: row.get_checked(15)?, + when_sec: row.get(14)?, + user_agent: row.get(15)?, addr: last_use_addr.0, }, - use_count: row.get_checked(17)?, + use_count: row.get(17)?, dirty: false, }) } diff --git a/db/check.rs b/db/check.rs index 8509661..e3c7aed 100644 --- a/db/check.rs +++ b/db/check.rs @@ -59,14 +59,13 @@ pub fn run(conn: &rusqlite::Connection, opts: &Options) -> Result<(), Error> { let mut garbage_stmt = conn.prepare_cached( "select composite_id from garbage where sample_file_dir_id = ?")?; let mut rows = dir_stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; + while let Some(row) = rows.next()? { let mut meta = schema::DirMeta::default(); - let dir_id: i32 = row.get_checked(0)?; - let dir_path: String = row.get_checked(1)?; - let dir_uuid: FromSqlUuid = row.get_checked(2)?; - let open_id = row.get_checked(3)?; - let open_uuid: FromSqlUuid = row.get_checked(4)?; + let dir_id: i32 = row.get(0)?; + let dir_path: String = row.get(1)?; + let dir_uuid: FromSqlUuid = row.get(2)?; + let open_id = row.get(3)?; + let open_uuid: FromSqlUuid = row.get(4)?; meta.db_uuid.extend_from_slice(&db_uuid.as_bytes()[..]); meta.dir_uuid.extend_from_slice(&dir_uuid.0.as_bytes()[..]); { @@ -79,9 +78,8 @@ pub fn run(conn: &rusqlite::Connection, opts: &Options) -> Result<(), Error> { let _dir = dir::SampleFileDir::open(&dir_path, &meta)?; let mut streams = read_dir(&dir_path, opts)?; let mut rows = garbage_stmt.query(&[&dir_id])?; - while let Some(row) = rows.next() { - let row = row?; - let id = CompositeId(row.get_checked(0)?); + while let Some(row) = rows.next()? { + let id = CompositeId(row.get(0)?); let s = streams.entry(id.stream()).or_insert_with(Stream::default); s.entry(id.recording()).or_insert_with(Recording::default).garbage_row = true; } @@ -95,10 +93,9 @@ pub fn run(conn: &rusqlite::Connection, opts: &Options) -> Result<(), Error> { select id, sample_file_dir_id from stream where sample_file_dir_id is not null "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let stream_id = row.get_checked(0)?; - let dir_id = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let stream_id = row.get(0)?; + let dir_id = row.get(1)?; let stream = match streams_by_dir.get_mut(&dir_id) { None => Stream::default(), Some(d) => d.remove(&stream_id).unwrap_or_else(Stream::default), @@ -224,15 +221,14 @@ fn compare_stream(conn: &rusqlite::Connection, stream_id: i32, opts: &Options, composite_id between ? and ? "#)?; let mut rows = stmt.query(&[&start.0, &end.0])?; - while let Some(row) = rows.next() { - let row = row?; - let id = CompositeId(row.get_checked(0)?); + while let Some(row) = rows.next()? { + let id = CompositeId(row.get(0)?); let s = RecordingSummary { - flags: row.get_checked(1)?, - bytes: row.get_checked::<_, i64>(2)? as u64, - duration: row.get_checked(3)?, - video_samples: row.get_checked(4)?, - video_sync_samples: row.get_checked(5)?, + flags: row.get(1)?, + bytes: row.get::<_, i64>(2)? as u64, + duration: row.get(3)?, + video_samples: row.get(4)?, + video_sync_samples: row.get(5)?, }; stream.entry(id.recording()) .or_insert_with(Recording::default) @@ -252,10 +248,9 @@ fn compare_stream(conn: &rusqlite::Connection, stream_id: i32, opts: &Options, composite_id between ? and ? "#)?; let mut rows = stmt.query(&[&start.0, &end.0])?; - while let Some(row) = rows.next() { - let row = row?; - let id = CompositeId(row.get_checked(0)?); - let video_index: Vec = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let id = CompositeId(row.get(0)?); + let video_index: Vec = row.get(1)?; let s = match summarize_index(&video_index) { Ok(s) => s, Err(e) => { @@ -280,9 +275,8 @@ fn compare_stream(conn: &rusqlite::Connection, stream_id: i32, opts: &Options, composite_id between ? and ? "#)?; let mut rows = stmt.query(&[&start.0, &end.0])?; - while let Some(row) = rows.next() { - let row = row?; - let id = CompositeId(row.get_checked(0)?); + while let Some(row) = rows.next()? { + let id = CompositeId(row.get(0)?); stream.entry(id.recording()) .or_insert_with(Recording::default) .integrity_row = true; diff --git a/db/db.rs b/db/db.rs index eeabe53..24a3e6e 100644 --- a/db/db.rs +++ b/db/db.rs @@ -587,11 +587,10 @@ fn init_recordings(conn: &mut rusqlite::Connection, stream_id: i32, camera: &Cam "#)?; let mut rows = stmt.query_named(&[(":stream_id", &stream_id)])?; let mut i = 0; - while let Some(row) = rows.next() { - let row = row?; - let start = recording::Time(row.get_checked(0)?); - let duration = recording::Duration(row.get_checked(1)?); - let bytes = row.get_checked(2)?; + while let Some(row) = rows.next()? { + let start = recording::Time(row.get(0)?); + let duration = recording::Duration(row.get(1)?); + let bytes = row.get(2)?; stream.add_recording(start .. start + duration, bytes); i += 1; } @@ -1277,9 +1276,8 @@ impl LockedDatabase { trace!("cache miss for recording {}", id); let mut stmt = self.conn.prepare_cached(GET_RECORDING_PLAYBACK_SQL)?; let mut rows = stmt.query_named(&[(":composite_id", &id.0)])?; - if let Some(row) = rows.next() { - let row = row?; - let video_index: VideoIndex = row.get_checked(0)?; + if let Some(row) = rows.next()? { + let video_index: VideoIndex = row.get(0)?; let result = f(&RecordingPlayback { video_index: &video_index.0[..] }); cache.insert(id.0, video_index.0); return result; @@ -1325,24 +1323,23 @@ impl LockedDatabase { video_sample_entry "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let id = row.get_checked(0)?; + while let Some(row) = rows.next()? { + let id = row.get(0)?; let mut sha1 = [0u8; 20]; - let sha1_vec: Vec = row.get_checked(1)?; + let sha1_vec: Vec = row.get(1)?; if sha1_vec.len() != 20 { bail!("video sample entry id {} has sha1 {} of wrong length", id, sha1_vec.len()); } sha1.copy_from_slice(&sha1_vec); - let data: Vec = row.get_checked(5)?; + let data: Vec = row.get(5)?; self.video_sample_entries_by_id.insert(id, Arc::new(VideoSampleEntry { id: id as i32, - width: row.get_checked::<_, i32>(2)? as u16, - height: row.get_checked::<_, i32>(3)? as u16, + width: row.get::<_, i32>(2)? as u16, + height: row.get::<_, i32>(3)? as u16, sha1, data, - rfc6381_codec: row.get_checked(4)?, + rfc6381_codec: row.get(4)?, })); } info!("Loaded {} video sample entries", @@ -1365,12 +1362,11 @@ impl LockedDatabase { sample_file_dir d left join open o on (d.last_complete_open_id = o.id); "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let id = row.get_checked(0)?; - let dir_uuid: FromSqlUuid = row.get_checked(2)?; - let open_id: Option = row.get_checked(3)?; - let open_uuid: Option = row.get_checked(4)?; + while let Some(row) = rows.next()? { + let id = row.get(0)?; + let dir_uuid: FromSqlUuid = row.get(2)?; + let open_id: Option = row.get(3)?; + let open_uuid: Option = row.get(4)?; let last_complete_open = match (open_id, open_uuid) { (Some(id), Some(uuid)) => Some(Open { id, uuid: uuid.0, }), (None, None) => None, @@ -1379,7 +1375,7 @@ impl LockedDatabase { self.sample_file_dirs_by_id.insert(id, SampleFileDir { id, uuid: dir_uuid.0, - path: row.get_checked(1)?, + path: row.get(1)?, dir: None, last_complete_open, garbage_needs_unlink: raw::list_garbage(&self.conn, id)?, @@ -1407,18 +1403,17 @@ impl LockedDatabase { camera; "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let id = row.get_checked(0)?; - let uuid: FromSqlUuid = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let id = row.get(0)?; + let uuid: FromSqlUuid = row.get(1)?; self.cameras_by_id.insert(id, Camera { id: id, uuid: uuid.0, - short_name: row.get_checked(2)?, - description: row.get_checked(3)?, - host: row.get_checked(4)?, - username: row.get_checked(5)?, - password: row.get_checked(6)?, + short_name: row.get(2)?, + description: row.get(3)?, + host: row.get(4)?, + username: row.get(5)?, + password: row.get(6)?, streams: Default::default(), }); self.cameras_by_uuid.insert(uuid.0, id); @@ -1446,26 +1441,25 @@ impl LockedDatabase { stream; "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let id = row.get_checked(0)?; - let type_: String = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let id = row.get(0)?; + let type_: String = row.get(1)?; let type_ = StreamType::parse(&type_).ok_or_else( || format_err!("no such stream type {}", type_))?; - let camera_id = row.get_checked(2)?; + let camera_id = row.get(2)?; let c = self .cameras_by_id .get_mut(&camera_id) .ok_or_else(|| format_err!("missing camera {} for stream {}", camera_id, id))?; - let flush_if_sec = row.get_checked(6)?; + let flush_if_sec = row.get(6)?; self.streams_by_id.insert(id, Stream { id, type_, camera_id, - sample_file_dir_id: row.get_checked(3)?, - rtsp_path: row.get_checked(4)?, - retain_bytes: row.get_checked(5)?, + sample_file_dir_id: row.get(3)?, + rtsp_path: row.get(4)?, + retain_bytes: row.get(5)?, flush_if_sec, range: None, sample_file_bytes: 0, @@ -1474,8 +1468,8 @@ impl LockedDatabase { bytes_to_add: 0, duration: recording::Duration(0), days: BTreeMap::new(), - next_recording_id: row.get_checked(7)?, - record: row.get_checked(8)?, + next_recording_id: row.get(7)?, + record: row.get(8)?, uncommitted: VecDeque::new(), synced_recordings: 0, on_live_segment: Vec::new(), @@ -1815,12 +1809,12 @@ pub fn init(conn: &mut rusqlite::Connection) -> Result<(), Error> { pub fn get_schema_version(conn: &rusqlite::Connection) -> Result, Error> { let ver_tables: i32 = conn.query_row_and_then( "select count(*) from sqlite_master where name = 'version'", - &[] as &[&ToSql], |row| row.get_checked(0))?; + &[] as &[&ToSql], |row| row.get(0))?; if ver_tables == 0 { return Ok(None); } Ok(Some(conn.query_row_and_then("select max(id) from version", &[] as &[&ToSql], - |row| row.get_checked(0))?)) + |row| row.get(0))?)) } /// The recording database. Abstracts away SQLite queries. Also maintains in-memory state diff --git a/db/raw.rs b/db/raw.rs index 7216e28..b5b3c5e 100644 --- a/db/raw.rs +++ b/db/raw.rs @@ -147,29 +147,28 @@ pub(crate) fn list_recordings_by_id( fn list_recordings_inner(mut rows: rusqlite::Rows, f: &mut FnMut(db::ListRecordingsRow) -> Result<(), Error>) -> Result<(), Error> { - while let Some(row) = rows.next() { - let row = row?; + while let Some(row) = rows.next()? { f(db::ListRecordingsRow { - id: CompositeId(row.get_checked(0)?), - run_offset: row.get_checked(1)?, - flags: row.get_checked(2)?, - start: recording::Time(row.get_checked(3)?), - duration_90k: row.get_checked(4)?, - sample_file_bytes: row.get_checked(5)?, - video_samples: row.get_checked(6)?, - video_sync_samples: row.get_checked(7)?, - video_sample_entry_id: row.get_checked(8)?, - open_id: row.get_checked(9)?, + id: CompositeId(row.get(0)?), + run_offset: row.get(1)?, + flags: row.get(2)?, + start: recording::Time(row.get(3)?), + duration_90k: row.get(4)?, + sample_file_bytes: row.get(5)?, + video_samples: row.get(6)?, + video_sync_samples: row.get(7)?, + video_sample_entry_id: row.get(8)?, + open_id: row.get(9)?, })?; } Ok(()) } pub(crate) fn get_db_uuid(conn: &rusqlite::Connection) -> Result { - conn.query_row("select uuid from meta", &[] as &[&ToSql], |row| -> Result { - let uuid: FromSqlUuid = row.get_checked(0)?; + Ok(conn.query_row("select uuid from meta", &[] as &[&ToSql], |row| -> rusqlite::Result { + let uuid: FromSqlUuid = row.get(0)?; Ok(uuid.0) - })? + })?) } /// Inserts the specified recording (for from `try_flush` only). @@ -313,8 +312,8 @@ pub(crate) fn get_range(conn: &rusqlite::Connection, stream_id: i32) // The minimum is straightforward, taking advantage of the start_time_90k index. let mut stmt = conn.prepare_cached(STREAM_MIN_START_SQL)?; let mut rows = stmt.query_named(&[(":stream_id", &stream_id)])?; - let min_start = match rows.next() { - Some(row) => recording::Time(row?.get_checked(0)?), + let min_start = match rows.next()? { + Some(row) => recording::Time(row.get(0)?), None => return Ok(None), }; @@ -325,10 +324,9 @@ pub(crate) fn get_range(conn: &rusqlite::Connection, stream_id: i32) let mut stmt = conn.prepare_cached(STREAM_MAX_START_SQL)?; let mut rows = stmt.query_named(&[(":stream_id", &stream_id)])?; let mut maxes_opt = None; - while let Some(row) = rows.next() { - let row = row?; - let row_start = recording::Time(row.get_checked(0)?); - let row_duration: i64 = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let row_start = recording::Time(row.get(0)?); + let row_duration: i64 = row.get(1)?; let row_end = recording::Time(row_start.0 + row_duration); let maxes = match maxes_opt { None => row_start .. row_end, @@ -353,9 +351,8 @@ pub(crate) fn list_garbage(conn: &rusqlite::Connection, dir_id: i32) let mut stmt = conn.prepare_cached( "select composite_id from garbage where sample_file_dir_id = ?")?; let mut rows = stmt.query(&[&dir_id])?; - while let Some(row) = rows.next() { - let row = row?; - garbage.insert(CompositeId(row.get_checked(0)?)); + while let Some(row) = rows.next()? { + garbage.insert(CompositeId(row.get(0)?)); } Ok(garbage) } @@ -370,13 +367,12 @@ pub(crate) fn list_oldest_recordings(conn: &rusqlite::Connection, start: Composi (":start", &start.0), (":end", &CompositeId::new(start.stream() + 1, 0).0), ])?; - while let Some(row) = rows.next() { - let row = row?; + while let Some(row) = rows.next()? { let should_continue = f(db::ListOldestRecordingsRow { - id: CompositeId(row.get_checked(0)?), - start: recording::Time(row.get_checked(1)?), - duration: row.get_checked(2)?, - sample_file_bytes: row.get_checked(3)?, + id: CompositeId(row.get(0)?), + start: recording::Time(row.get(1)?), + duration: row.get(2)?, + sample_file_bytes: row.get(3)?, }); if !should_continue { break; diff --git a/db/upgrade/mod.rs b/db/upgrade/mod.rs index 92c217e..dc820a0 100644 --- a/db/upgrade/mod.rs +++ b/db/upgrade/mod.rs @@ -54,7 +54,7 @@ pub struct Args<'a> { fn set_journal_mode(conn: &rusqlite::Connection, requested: &str) -> Result<(), Error> { assert!(!requested.contains(';')); // quick check for accidental sql injection. let actual = conn.query_row(&format!("pragma journal_mode = {}", requested), &[] as &[&ToSql], - |row| row.get_checked::<_, String>(0))??; + |row| row.get::<_, String>(0))?; info!("...database now in journal_mode {} (requested {}).", actual, requested); Ok(()) } @@ -70,7 +70,7 @@ pub fn run(args: &Args, conn: &mut rusqlite::Connection) -> Result<(), Error> { assert_eq!(upgraders.len(), db::EXPECTED_VERSION as usize); let old_ver = conn.query_row("select max(id) from version", &[] as &[&ToSql], - |row| row.get_checked(0))??; + |row| row.get(0))?; if old_ver > db::EXPECTED_VERSION { bail!("Database is at version {}, later than expected {}", old_ver, db::EXPECTED_VERSION); diff --git a/db/upgrade/v0_to_v1.rs b/db/upgrade/v0_to_v1.rs index 3cb134f..001416a 100644 --- a/db/upgrade/v0_to_v1.rs +++ b/db/upgrade/v0_to_v1.rs @@ -144,9 +144,8 @@ fn fill_recording(tx: &rusqlite::Transaction) -> Result = HashMap::new(); - while let Some(row) = rows.next() { - let row = row?; - let camera_id: i32 = row.get_checked(0)?; + while let Some(row) = rows.next()? { + let camera_id: i32 = row.get(0)?; let camera_state = camera_state.entry(camera_id).or_insert_with(|| { CameraState{ current_run: None, @@ -155,17 +154,17 @@ fn fill_recording(tx: &rusqlite::Transaction) -> Result = row.get_checked(9)?; - let video_index: Vec = row.get_checked(10)?; - let old_id: i32 = row.get_checked(11)?; + let sample_file_bytes: i32 = row.get(1)?; + let start_time_90k: i64 = row.get(2)?; + let duration_90k: i32 = row.get(3)?; + let local_time_delta_90k: i64 = row.get(4)?; + let video_samples: i32 = row.get(5)?; + let video_sync_samples: i32 = row.get(6)?; + let video_sample_entry_id: i32 = row.get(7)?; + let sample_file_uuid: db::FromSqlUuid = row.get(8)?; + let sample_file_sha1: Vec = row.get(9)?; + let video_index: Vec = row.get(10)?; + let old_id: i32 = row.get(11)?; let trailing_zero = has_trailing_zero(&video_index).unwrap_or_else(|e| { warn!("recording {}/{} (sample file {}, formerly recording {}) has corrupt \ video_index: {}", @@ -218,18 +217,17 @@ fn fill_camera(tx: &rusqlite::Transaction, camera_state: HashMap = row.get_checked(1)?; - let short_name: String = row.get_checked(2)?; - let description: String = row.get_checked(3)?; - let host: String = row.get_checked(4)?; - let username: String = row.get_checked(5)?; - let password: String = row.get_checked(6)?; - let main_rtsp_path: String = row.get_checked(7)?; - let sub_rtsp_path: String = row.get_checked(8)?; - let retain_bytes: i64 = row.get_checked(9)?; + while let Some(row) = rows.next()? { + let id: i32 = row.get(0)?; + let uuid: Vec = row.get(1)?; + let short_name: String = row.get(2)?; + let description: String = row.get(3)?; + let host: String = row.get(4)?; + let username: String = row.get(5)?; + let password: String = row.get(6)?; + let main_rtsp_path: String = row.get(7)?; + let sub_rtsp_path: String = row.get(8)?; + let retain_bytes: i64 = row.get(9)?; insert.execute_named(&[ (":id", &id), (":uuid", &uuid), diff --git a/db/upgrade/v1_to_v2.rs b/db/upgrade/v1_to_v2.rs index 23be769..dfb1d1e 100644 --- a/db/upgrade/v1_to_v2.rs +++ b/db/upgrade/v1_to_v2.rs @@ -298,7 +298,7 @@ fn verify_dir_contents(sample_file_path: &str, tx: &rusqlite::Transaction) -> Re from (select count(*) as c from recording) a, (select count(*) as c from reserved_sample_files) b; - "#, &[] as &[&ToSql], |r| r.get_checked(0))??; + "#, &[] as &[&ToSql], |r| r.get(0))?; let mut files = ::fnv::FnvHashSet::with_capacity_and_hasher(n as usize, Default::default()); for e in fs::read_dir(sample_file_path)? { let e = e?; @@ -330,9 +330,8 @@ fn verify_dir_contents(sample_file_path: &str, tx: &rusqlite::Transaction) -> Re { let mut stmt = tx.prepare(r"select sample_file_uuid from recording_playback")?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let uuid: crate::db::FromSqlUuid = row.get_checked(0)?; + while let Some(row) = rows.next()? { + let uuid: crate::db::FromSqlUuid = row.get(0)?; if !files.remove(&uuid.0) { bail!("{} is missing from dir {}!", uuid.0, sample_file_path); } @@ -341,9 +340,8 @@ fn verify_dir_contents(sample_file_path: &str, tx: &rusqlite::Transaction) -> Re let mut stmt = tx.prepare(r"select uuid from reserved_sample_files")?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let uuid: crate::db::FromSqlUuid = row.get_checked(0)?; + while let Some(row) = rows.next()? { + let uuid: crate::db::FromSqlUuid = row.get(0)?; files.remove(&uuid.0); } @@ -369,14 +367,13 @@ fn fix_video_sample_entry(tx: &rusqlite::Transaction) -> Result<(), Error> { insert into video_sample_entry values (:id, :sha1, :width, :height, :rfc6381_codec, :data) "#)?; let mut rows = select.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let data: Vec = row.get_checked(4)?; + while let Some(row) = rows.next()? { + let data: Vec = row.get(4)?; insert.execute_named(&[ - (":id", &row.get_checked::<_, i32>(0)?), - (":sha1", &row.get_checked::<_, Vec>(1)?), - (":width", &row.get_checked::<_, i32>(2)?), - (":height", &row.get_checked::<_, i32>(3)?), + (":id", &row.get::<_, i32>(0)?), + (":sha1", &row.get::<_, Vec>(1)?), + (":width", &row.get::<_, i32>(2)?), + (":height", &row.get::<_, i32>(3)?), (":rfc6381_codec", &rfc6381_codec_from_sample_entry(&data)?), (":data", &data), ])?; diff --git a/db/upgrade/v2_to_v3.rs b/db/upgrade/v2_to_v3.rs index a98e153..0ccf6a5 100644 --- a/db/upgrade/v2_to_v3.rs +++ b/db/upgrade/v2_to_v3.rs @@ -58,11 +58,11 @@ fn open_sample_file_dir(tx: &rusqlite::Transaction) -> Result Result<(), Error> recording_playback "#)?; let mut rows = stmt.query(&[] as &[&ToSql])?; - while let Some(row) = rows.next() { - let row = row?; - let id = db::CompositeId(row.get_checked(0)?); - let sample_file_uuid: FromSqlUuid = row.get_checked(1)?; + while let Some(row) = rows.next()? { + let id = db::CompositeId(row.get(0)?); + let sample_file_uuid: FromSqlUuid = row.get(1)?; let from_path = get_uuid_pathname(sample_file_uuid.0); let to_path = get_id_pathname(id); let r = unsafe { dir::renameat(&d.fd, from_path.as_ptr(), &d.fd, to_path.as_ptr()) }; diff --git a/guide/install-manual.md b/guide/install-manual.md index 6ab5b68..f49cbe9 100644 --- a/guide/install-manual.md +++ b/guide/install-manual.md @@ -45,7 +45,7 @@ all non-Rust dependencies: pkgconf \ tzdata -Next, you need Rust 1.32+ and Cargo. The easiest way to install them is by +Next, you need Rust 1.33+ and Cargo. The easiest way to install them is by following the instructions at [rustup.rs](https://www.rustup.rs/). Finally, building the UI requires [yarn](https://yarnpkg.com/en/). diff --git a/scripts/script-functions.sh b/scripts/script-functions.sh index fede9a9..0ee8fb1 100755 --- a/scripts/script-functions.sh +++ b/scripts/script-functions.sh @@ -40,7 +40,7 @@ fi NODE_MIN_VERSION="8" YARN_MIN_VERSION="1.0" CARGO_MIN_VERSION="0.2" -RUSTC_MIN_VERSION="1.32" +RUSTC_MIN_VERSION="1.33" FFMPEG_MIN_VERSION="55.1.101" FFMPEG_RELEASE_VERSION="3.4"