feat(lsm): require changes to be committed before writing to persistent
storagefeature/50-one-time-keys
							parent
							
								
									d64fec048f
								
							
						
					
					
						commit
						3dce25239b
					
				| 
						 | 
				
			
			@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 | 
			
		|||
 | 
			
		||||
## [Unreleased](https://git.rustybever.be/Chewing_Bever/lander/src/branch/dev)
 | 
			
		||||
 | 
			
		||||
## Fixed
 | 
			
		||||
 | 
			
		||||
* Failed uploads now no longer leave behind a partial entry file
 | 
			
		||||
 | 
			
		||||
## [0.2.1](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.1)
 | 
			
		||||
 | 
			
		||||
### Added
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,8 @@ lnm_http_step_err lander_post_paste_secure(lnm_http_conn *conn);
 | 
			
		|||
 | 
			
		||||
lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn);
 | 
			
		||||
 | 
			
		||||
lnm_http_step_err lander_commit_entry(lnm_http_conn *conn);
 | 
			
		||||
 | 
			
		||||
lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn);
 | 
			
		||||
 | 
			
		||||
lnm_http_step_err lander_remove_entry(lnm_http_conn *conn);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -159,6 +159,15 @@ lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
 | 
			
		|||
lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store,
 | 
			
		||||
                               const lsm_str *key);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Commit any changes to the persistent storage. Any changes, insertions or
 | 
			
		||||
 * deletions that occured without a commit are reverted when the handle is
 | 
			
		||||
 * closed.
 | 
			
		||||
 *
 | 
			
		||||
 * @param handle handle to the entry
 | 
			
		||||
 */
 | 
			
		||||
lsm_error lsm_entry_commit(lsm_entry_handle *handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Close an open entry handle.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,7 +157,8 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle);
 | 
			
		|||
lsm_error lsm_entry_data_open_write(lsm_entry_handle *handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove the entry's data file if present and close its handle.
 | 
			
		||||
 * Remove the entry's data file if present and close its handle. Any uncommitted
 | 
			
		||||
 * changes will be reverted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param handle handle to the entry
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,31 +58,42 @@ lsm_error lsm_entry_handle_init(lsm_entry_handle **out) {
 | 
			
		|||
  return lsm_error_ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lsm_entry_close(lsm_entry_handle *handle) {
 | 
			
		||||
  if (handle->f != NULL) {
 | 
			
		||||
    fclose(handle->f);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool state_new = handle->states & lsm_entry_handle_state_new;
 | 
			
		||||
  bool state_removed = handle->states & lsm_entry_handle_state_removed;
 | 
			
		||||
  /* bool state_updated = handle->states & lsm_entry_handle_state_updated; */
 | 
			
		||||
lsm_error lsm_entry_commit(lsm_entry_handle *handle) {
 | 
			
		||||
  uint8_t state_new = handle->states & lsm_entry_handle_state_new;
 | 
			
		||||
  uint8_t state_removed = handle->states & lsm_entry_handle_state_removed;
 | 
			
		||||
 | 
			
		||||
  // Clean new entry
 | 
			
		||||
  if (state_new && !state_removed) {
 | 
			
		||||
    lsm_entry_disk_insert(handle);
 | 
			
		||||
  }
 | 
			
		||||
  // New entry that was removed before being written to disk; only its data file
 | 
			
		||||
  // needs to be removed if present
 | 
			
		||||
  else if (state_new && state_removed) {
 | 
			
		||||
    lsm_entry_data_remove(handle);
 | 
			
		||||
 | 
			
		||||
    lsm_entry_free(handle->wrapper->entry);
 | 
			
		||||
    handle->wrapper->entry = NULL;
 | 
			
		||||
    LSM_RES(lsm_entry_disk_insert(handle));
 | 
			
		||||
  }
 | 
			
		||||
  // Previously stored entry that needs to be removed; should be removed from db
 | 
			
		||||
  // file as well
 | 
			
		||||
  else if (state_removed && !state_new) {
 | 
			
		||||
    lsm_entry_disk_remove(handle);
 | 
			
		||||
    LSM_RES(lsm_entry_disk_remove(handle));
 | 
			
		||||
 | 
			
		||||
    lsm_entry_free(handle->wrapper->entry);
 | 
			
		||||
    handle->wrapper->entry = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reset states after committing current changes
 | 
			
		||||
  handle->states = 0;
 | 
			
		||||
 | 
			
		||||
  return lsm_error_ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lsm_entry_close(lsm_entry_handle *handle) {
 | 
			
		||||
  if (handle->f != NULL) {
 | 
			
		||||
    fclose(handle->f);
 | 
			
		||||
    handle->f = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint8_t state_new = handle->states & lsm_entry_handle_state_new;
 | 
			
		||||
  /* bool state_updated = handle->states & lsm_entry_handle_state_updated; */
 | 
			
		||||
 | 
			
		||||
  // New entries create a wrapper in the trie that should be removed if not
 | 
			
		||||
  // committed
 | 
			
		||||
  if (state_new) {
 | 
			
		||||
    lsm_entry_data_remove(handle);
 | 
			
		||||
 | 
			
		||||
    lsm_entry_free(handle->wrapper->entry);
 | 
			
		||||
    handle->wrapper->entry = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -328,7 +339,6 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle) {
 | 
			
		|||
  return lsm_error_ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
lsm_error lsm_entry_data_remove(lsm_entry_handle *handle) {
 | 
			
		||||
  const lsm_entry *entry = handle->wrapper->entry;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "lnm/http/loop.h"
 | 
			
		||||
#include "lnm/log.h"
 | 
			
		||||
#include "lnm/loop.h"
 | 
			
		||||
 | 
			
		||||
#include "lander.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -25,3 +26,12 @@ lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn) {
 | 
			
		|||
             ? lnm_http_step_err_done
 | 
			
		||||
             : lnm_http_step_err_io_needed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
lnm_http_step_err lander_commit_entry(lnm_http_conn *conn) {
 | 
			
		||||
  lnm_http_loop_ctx *ctx = conn->ctx;
 | 
			
		||||
  lander_ctx *c_ctx = ctx->c;
 | 
			
		||||
 | 
			
		||||
  lsm_entry_commit(c_ctx->entry);
 | 
			
		||||
 | 
			
		||||
  return lnm_http_step_err_done;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										11
									
								
								src/main.c
								
								
								
								
							| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include "lnm/http/loop.h"
 | 
			
		||||
#include "lnm/http/route.h"
 | 
			
		||||
#include "lnm/log.h"
 | 
			
		||||
 | 
			
		||||
#include "lander.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -30,54 +31,64 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
 | 
			
		|||
  lnm_http_router_add(&route, router, lnm_http_method_delete, "/:key");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_remove_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/s/");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_redirect, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/sl/");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_redirect_secure, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/s/:key");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_redirect, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/p/");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_paste, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/pl/");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_paste_secure, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/p/:key");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_paste, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/f/");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_file, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/fl/");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_file_secure, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_router_add(&route, router, lnm_http_method_post, "/f/:key");
 | 
			
		||||
  lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_post_file, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
 | 
			
		||||
  lnm_http_route_step_append(route, lander_commit_entry, true);
 | 
			
		||||
 | 
			
		||||
  lnm_http_loop_router_set(hl, router);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue