Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #load "extLib.cma"
- open Printf
- (* Record changes and report changes *)
- module HasChanged =
- struct
- type change_rec = { fn: string ; ov: string ; nv: string ; }
- let create () = DynArray.create () ;;
- let to_list changes = DynArray.to_list changes ;;
- let change fn ov nv = {fn=fn; ov=ov; nv=nv;}
- let add_maybe changes fn ov nv =
- if ov != nv then DynArray.add changes (change fn ov nv) ;;
- let field_names a b =
- if String.length a > 0
- then a ^ "," ^ b.fn
- else b.fn ;;
- let field_values a b =
- if String.length a > 0
- then a ^ ",'" ^ b.nv ^ "'"
- else "'" ^ b.nv ^ "'";;
- let field_name_value_pair a b =
- if String.length a > 0
- then a ^ "," ^ b.fn ^ "='" ^ b.nv ^ "'"
- else b.fn ^ "='" ^ b.nv ^ "'" ;;
- end ;;
- let update_stmt table id changes =
- let vp = List.fold_left HasChanged.field_name_value_pair "" changes in
- sprintf "UPDATE %s SET %s WHERE id=%i" table vp id ;;
- let add_callback v f = DynArray.add v f ;;
- (* This entire module will be auto-generated based on table information *)
- module User =
- struct
- type user = {
- mutable id: int ;
- mutable code: string ;
- mutable password: string ;
- mutable first_name: string ;
- mutable last_name: string ;
- mutable version: int ;
- mutable original: user option ; }
- let before_create = DynArray.create ()
- let before_update = DynArray.create ()
- let before_insert = DynArray.create ()
- let create id code password first_name last_name version =
- { id=id; code=code; password=password; first_name=first_name;
- last_name=last_name; version=0; original=None; }
- let empty = create 0 "" "" "" "" 0
- let changes u =
- let do_change_compare u1 u2 =
- let changes = HasChanged.create () in
- HasChanged.add_maybe changes "id" (string_of_int u1.id) (string_of_int u2.id) ;
- HasChanged.add_maybe changes "code" u1.code u2.code ;
- HasChanged.add_maybe changes "password" u1.password u2.password ;
- HasChanged.add_maybe changes "first_name" u1.first_name u2.first_name ;
- HasChanged.add_maybe changes "last_name" u1.last_name u2.last_name ;
- HasChanged.add_maybe changes "version" (string_of_int u1.version) (string_of_int u2.version) ;
- HasChanged.to_list changes
- in
- match u.original with
- | Some orig -> do_change_compare orig u
- | None -> do_change_compare empty u ;;
- let clear_changes u =
- u.original <- (Some (create u.id u.code u.password u.first_name u.last_name u.version))
- let insert u =
- DynArray.iter (fun f -> f u) before_insert;
- let stmt = sprintf ("INSERT INTO users (code,password,first_name,last_name,version) VALUES ('%s','%s','%s','%s',%i)")
- u.code u.password u.first_name u.last_name u.version in
- u.id <- 10 ;
- clear_changes u ;
- stmt ;;
- let update u =
- DynArray.iter (fun f -> f u) before_update;
- let stmt = update_stmt "users" u.id (changes u) in
- clear_changes u ;
- stmt ;;
- let save u = if u.id == 0 then insert u else update u ;;
- end ;;
- (* Methods that I use to extend the base functionality of the auto-generated
- User module *)
- let user_cb_set_defaults u = u.User.version <- 1 ;;
- let user_cb_increment_version u = u.User.version <- u.User.version + 1 ;;
- let user_full_name u = sprintf "%s %s" u.User.first_name u.User.last_name ;;
- let user_blinded_name u = sprintf "%s %c." u.User.first_name (String.get u.User.last_name 0) ;;
- (* Simple callback interface *)
- add_callback User.before_insert user_cb_set_defaults ;;
- add_callback User.before_update user_cb_increment_version ;;
- (* Play around a bit *)
- let u=User.create 0 "john" "doe" "John" "Doe" 0 in
- printf "%s\n" (User.save u) ;
- u.User.first_name <- "Jane" ;
- u.User.last_name <- "Smith" ;
- printf "%s\n" (user_blinded_name u) ;
- u.User.code <- "jsmith" ;
- printf "%s\n" (User.save u) ;;
Add Comment
Please, Sign In to add comment