http://www.perlmonks.org?node_id=428241

Here is a perl module containing subroutines that are embedded in a lex/yacc sql parser in order to translate a low-level database structure into a higher level data-warehouse structure at run-time.

The data-warehouse structure is represented in a .tables file

# ==================================================================== +========== # obj_srvr.tables # # This file contains the layout and associated subroutine referencess + for the # virtual tables served by Obj_Srvr.pm. # # Driver routines must return reference to an array of hash refs (rec +ords). # All supporting routines must return only 1 record per driver routin +e # record. To use supporting routines that return an array of records + (like # schedule() ), create a wrapper driver routine that adds in the supp +orting # records and returns an expanded array (see stu_schedule for an exam +ple). # # These will be included in Obj_Srvr.pm at the package level. # ==================================================================== +========== # ========================== # Table Driver Subroutines # ========================== # note: could be multiple subs for a table name # # table name driver sub name driver sub ref %table_objs = ( "term_students" => { "subname" => "term_students" +, "subref" => \&term_students + }, "stu_schedule" => { "subname" => "stu_schedule", "subref" => \&stu_schedule +}, "term_graduates" => { "subname" => "term_graduates +", "subref" => \&term_graduate +s }, "term_appls" => { "subname" => "term_appls", "subref" => \&appls_for_ter +m }, "term_admits" => { "subname" => "term_admits", "subref" => \&term_admits } +, "new_fr" => { "subname" => "new_fr", "subref" => \&new_fr }, "new_tr" => { "subname" => "new_tr", "subref" => \&new_tr }, "new_fr_tr" => { "subname" => "new_fr_tr", "subref" => \&new_fr_tr }, "new_fr_sched" => { "subname" => "new_fr_sched", "subref" => \&new_fr_sched +}, "new_tr_sched" => { "subname" => "new_tr_sched", "subref" => \&new_tr_sched +}, "new_fr_tr_sched" => { "subname" => "new_fr_tr_sche +d", "subref" => \&new_fr_tr_sch +ed }, "term_balances" => { "subname" => "term_balances" +, "subref" => \&term_balances + }, "term_faculty" => { "subname" => "term_fac_sched +", "subref" => \&term_fac_sche +d }, "term_schedule" => { "subname" => "term_schedule" +, "subref" => \&term_schedule + }, "term_recruits" => { "subname" => "term_recruits" +, "subref" => \&term_recruits + } ); # =================== # Table Definitions # =================== %obj_accessor = ( "term_students" => { "term" => { "subname" => "SELF", "size" => 6 }, "level" => { "subname" => "SELF", "size" => 2 }, "confidential" => { "subname" => "SELF", "size" => 1 }, "dead" => { "subname" => "SELF", "size" => 1 }, "majr_code" => { "subname" => "SELF", "size" => 4 }, "minr_code" => { "subname" => "SELF", "size" => 4 }, "con1_code" => { "subname" => "SELF", "size" => 4 }, "con2_code" => { "subname" => "SELF", "size" => 4 }, "con3_code" => { "subname" => "SELF", "size" => 4 }, "major" => { "subname" => "SELF", "size" => 30 }, "minor" => { "subname" => "SELF", "size" => 30 }, "conc1" => { "subname" => "SELF", "size" => 30 }, "conc2" => { "subname" => "SELF", "size" => 30 }, "conc3" => { "subname" => "SELF", "size" => 30 }, "resident" => { "subname" => "SELF", "size" => 1 }, "deg_plan" => { "subname" => "SELF", "size" => 3 }, "admt_code" => { "subname" => "SELF", "size" => 2 }, "admit_term" => { "subname" => "SELF", "size" => 6 }, "styp_code" => { "subname" => "SELF", "size" => 1 }, "orsn_code" => { "subname" => "SELF", "size" => 1 }, "rate_code" => { "subname" => "SELF", "size" => 5 }, "coll_code" => { "subname" => "SELF", "size" => 2 }, "academic_level" => { "subname" => "academic_lev +el", "subref" => \&academic_le +vel, "field" => "academic_lev +el", "size" => 30 }, "advisor_lname" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_lname +", "size" => 60 } +, "advisor_fname" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_fname +", "size" => 15 } +, "advisor_mi" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_mi", "size" => 15 } +, "advisor_vnum" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_vnum" +, "size" => 9 } +, "cum_gpa" => { "subname" => "all_gpa_o +", "subref" => \&all_gpa, "field" => "gpa", "size" => 4, "datatype" => "numeric" + }, "total_hrs" => { "subname" => "all_gpa_o +", "subref" => \&all_gpa, "field" => "total_hrs +", "size" => 7, "datatype" => "numeric" + }, "term_hrs" => { "subname" => "term_hrs", + "subref" => \&term_hrs +, "field" => "term_hrs" +, "size" => 5, "datatype" => "numeric" + }, "class" => { "subname" => "class", "subref" => \&class_by_p +idm, "field" => "class", "size" => 2 }, "sat" => { "subname" => "SAT", "subref" => \&SAT, "field" => "SAT", "size" => 5, "datatype" => "numeric" +}, "satm" => { "subname" => "SAT", "subref" => \&SAT, "field" => "SATM", "size" => 5, "datatype" => "numeric" + }, "satv" => { "subname" => "SAT", "subref" => \&SAT, "field" => "SATV", "size" => 5, "datatype" => "numeric" + }, "act" => { "subname" => "ACT", "subref" => \&ACT, "field" => "ACT", "size" => 5, "datatype" => "numeric" +}, "acte" => { "subname" => "ACT", "subref" => \&ACT, "field" => "ACTE", "size" => 5, "datatype" => "numeric" + }, "actm" => { "subname" => "ACT", "subref" => \&ACT, "field" => "ACTM", "size" => 5, "datatype" => "numeric" + }, "actn" => { "subname" => "ACT", "subref" => \&ACT, "field" => "ACTN", "size" => 5, "datatype" => "numeric" + }, "acts" => { "subname" => "ACT", "subref" => \&ACT, "field" => "ACTS", "size" => 5, "datatype" => "numeric" + }, "last_tr_coll" => { "subname" => "last_tr_co +ll", "subref" => \&last_tr_c +oll, "field" => "coll_desc" +, "size" => 30 }, "last_tr_coll_code" => { "subname" => "last_tr_c +oll", "subref" => \&last_tr_c +oll, "field" => "prior_coll +", "size" => 6 }, "fr_cohort" => { "subname" => "fr_cohort", "subref" => \&fr_cohort, "field" => "fr_cohort", "size" => 10 }, "hs_code" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "hs_code", "size" => 6 }, "high_school" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "hs_desc", "size" => 30 } }, "term_faculty" => { "term" => { "subname" => "SELF", "size" => 6 }, "gender" => { "subname" => "SELF", "size" => 1 }, "ethnicity" => { "subname" => "SELF", "size" => 30 }, "dept" => { "subname" => "SELF", "size" => 30 }, "divs" => { "subname" => "SELF", "size" => 30 }, "crn" => { "subname" => "SELF", "size" => 5 }, "subject" => { "subname" => "SELF", "size" => 4 }, "course" => { "subname" => "SELF", "size" => 5 }, "title" => { "subname" => "SELF", "size" => 30 }, "sched_code" => { "subname" => "SELF", "size" => 3 }, "enrolled" => { "subname" => "SELF", "size" => 4, "datatype" => "numeric" }, "credit_hrs" => { "subname" => "SELF", "size" => 5, "datatype" => "numeric" }, # Note: we can provide ID fields from SIS using + %id_addr # further below without overwriting ethni +city above # which came from HR, because add2hash wo +n't replace # a hash key that already exists. }, "term_balances" => { "term" => { "subname" => "SELF", "size" => 6 }, "category" => { "subname" => "SELF", "size" => 3 }, "balance" => { "subname" => "SELF", "size" => 14, "datatype" => "numeric" }, "ssn" => { "subname" => "SELF", "size" => 9 } +, "academic_level" => { "subname" => "academic_lev +el", "subref" => \&academic_le +vel, "field" => "academic_lev +el", "size" => 30 }, "advisor_lname" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_lname +", "size" => 60 } +, "advisor_fname" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_fname +", "size" => 15 } +, "advisor_mi" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_mi", "size" => 15 } +, "advisor_vnum" => { "subname" => "advisor", + "subref" => \&advisor, "field" => "adv_vnum" +, "size" => 9 } +, "term_hrs" => { "subname" => "term_hrs", + "subref" => \&term_hrs +, "field" => "term_hrs" +, "size" => 5, "datatype" => "numeric" + } }, "term_recruits" => { "term" => { "subname" => "SELF", "size" => 6 }, "level" => { "subname" => "SELF", "size" => 2 }, "major" => { "subname" => "SELF", "size" => 30 }, "confidential" => { "subname" => "SELF", "size" => 1 }, "hs_code" => { "subname" => "SELF", "size" => 6 }, "high_school" => { "subname" => "SELF", "size" => 30 }, "ethnicity" => { "subname" => "SELF", "size" => 30 } +, "hs_gpa" => { "subname" => "SELF", "size" => 4, "datatype" => "numeric" + }, "recruit_type" => { "subname" => "SELF", "size" => 30 } +, "level_of_interest" => { "subname" => "SELF", "size" => 30 } +, "recr_status" => { "subname" => "recr_stat +us", "subref" => \&recr_sta +tus, "field" => "recr_stat +us", "size" => 30 }, "last_tr_coll" => { "subname" => "coll_info" +, "subref" => \&coll_info +, "field" => "coll_desc" +, "size" => 30 }, "last_tr_coll_code" => { "subname" => "coll_info +", "subref" => \&coll_in +fo, "field" => "prior_col +l", "size" => 6 }, "college_state" => { "subname" => "coll_info +", "subref" => \&coll_inf +o, "field" => "sbgi_stat +e", "size" => 3 }, "college_county" => { "subname" => "coll_info +", "subref" => \&coll_inf +o, "field" => "sbgi_coun +ty", "size" => 30 }, "college_city" => { "subname" => "coll_info +", "subref" => \&coll_inf +o, "field" => "sbgi_city +", "size" => 20 }, "hs_state" => { "subname" => "hs_info", "subref" => \&sbgi_inf +o, "field" => "sbgi_stat +e", "size" => 3 }, "hs_county" => { "subname" => "hs_info", "subref" => \&sbgi_inf +o, "field" => "sbgi_coun +ty", "size" => 30 }, "hs_city" => { "subname" => "hs_info", "subref" => \&sbgi_inf +o, "field" => "sbgi_city +", "size" => 20 } }, "term_appls" => { "term" => { "subname" => "SELF", "size" => 6 }, "level" => { "subname" => "SELF", "size" => 2 }, "residence" => { "subname" => "SELF", "size" => 1 }, "appl_date" => { "subname" => "SELF", "size" => 10, "datatype" => "date" }, "admt_code" => { "subname" => "SELF", "size" => 2 }, "major" => { "subname" => "SELF", "size" => 30 }, "college_code" => { "subname" => "SELF", "size" => 6 }, "college" => { "subname" => "SELF", "size" => 30 }, "college_state" => { "subname" => "SELF", "size" => 3 }, "decision" => { "subname" => "app_decsn" +, "subref" => \&app_decs +n, "field" => "decision" +, "size" => 2 }, "accepted" => { "subname" => "app_decsn" +, "subref" => \&app_decs +n, "field" => "accepted" +, "size" => 1 } }, "term_admits" => { "term" => { "subname" => "SELF", "size" => 6 }, "level" => { "subname" => "SELF", "size" => 2 }, "decision" => { "subname" => "SELF", "size" => 2 }, "decision_date" => { "subname" => "SELF", "size" => 10, "datatype" => "date" }, "appl_date" => { "subname" => "SELF", "size" => 10, "datatype" => "date" }, "admt_code" => { "subname" => "SELF", "size" => 2 }, "accepted_flg" => { "subname" => "SELF", "size" => 1 }, "resident" => { "subname" => "SELF", "size" => 1 }, "enrolled" => { "subname" => "enrolled_yn", "subref" => \&enrolled_yn, "field" => "enrolled", "size" => 1 }, "major" => { "subname" => "student", "subref" => \&student2, "field" => "major", "size" => 30 }, "hs_code" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "hs_code", "size" => 6 }, "high_school" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "hs_desc", "size" => 30 }, "hs_gpa" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "gpa", "size" => 4, "datatype" => "numeric" }, "hs_rank" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "rank", "size" => 4, "datatype" => "numeric" }, "hs_percentile" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "percentile", "size" => 5, "datatype" => "numeric" }, "hs_grad_date" => { "subname" => "hs_gpa", "subref" => \&hs_gpa, "field" => "grad_date", "size" => 10, "datatype" => "date" }, "level_of_interest" => { "subname" => "recruit", + "subref" => \&recruit, "field" => "level_of_ +interest", "size" => 30 }, "contact" => { "subname" => "contact", "subref" => \&contact, "field" => "contact", "size" => 30 } }, "term_schedule" => { "term" => { "subname" => "SELF", "size" => 6 }, "crn" => { "subname" => "SELF", "size" => 5 }, "subj" => { "subname" => "SELF", "size" => 4 }, "crse" => { "subname" => "SELF", "size" => 5 }, "crse_title" => { "subname" => "SELF", "size" => 30 }, "schd_code" => { "subname" => "SELF", "size" => 3 }, "enrl" => { "subname" => "SELF", "size" => 4, "datatype" => "numeric" }, "max_enrl" => { "subname" => "SELF", "size" => 4, "datatype" => "numeric" }, "seats_avail" => { "subname" => "SELF", "size" => 4, "datatype" => "numeric" }, "credit_hrs" => { "subname" => "SELF", "size" => 5, "datatype" => "numeric" }, "bldg" => { "subname" => "SELF", "size" => 6 }, "room" => { "subname" => "SELF", "size" => 10 }, "time" => { "subname" => "SELF", "size" => 9 }, "days" => { "subname" => "SELF", "size" => 7 }, "capacity" => { "subname" => "SELF", "size" => 4, "datatype" => "numeric" }, "instructor_lname" => { "subname" => "primary_in +structor", "subref" => \&primary_instruct +or, "field" => "lname", "size" => 60 }, "instructor_fname" => { "subname" => "primary_in +structor", "subref" => \&primary_instruct +or, "field" => "fname", "size" => 15 }, "instructor_mname" => { "subname" => "primary_in +structor", "subref" => \&primary_instruct +or, "field" => "full_mname", "size" => 15 }, "instructor_vnum" => { "subname" => "primary_in +structor", "subref" => \&primary_instruct +or, "field" => "vnum", "size" => 9 } } ); my %id_addr = ( "lname" => { "subname" => "id", "subref" => \&id, "field" => "lname", "size" => 60 }, "fname" => { "subname" => "id", "subref" => \&id, "field" => "fname", "size" => 15 }, "mname" => { "subname" => "id", "subref" => \&id, "field" => "full_mname", "size" => 15 }, "vnum" => { "subname" => "id", "subref" => \&id, "field" => "vnum", "size" => 9 }, "confidential" => { "subname" => "id", "subref" => \&id, "field" => "confidential", "size" => 1 }, "deceased" => { "subname" => "id", "subref" => \&id, "field" => "dead", "size" => 1 }, "citizen" => { "subname" => "id", "subref" => \&id, "field" => "citz", "size" => 2 }, "gender" => { "subname" => "id", "subref" => \&id, "field" => "gender", "size" => 1 }, "ethn_code" => { "subname" => "id", "subref" => \&id, "field" => "ethn_code", "size" => 2 }, "ethnicity" => { "subname" => "id", "subref" => \&id, "field" => "ethnicity", "size" => 30 }, "birthdate" => { "subname" => "id", "subref" => \&id, "field" => "birth_date", "size" => 10, "datatype" => "date" }, "age" => { "subname" => "id", "subref" => \&id, "field" => "age", "size" => 3, "datatype" => "numeric" }, "email" => { "subname" => "stu_email", "subref" => \&stu_email, "field" => "email_address", "size" => 90 }, "street1" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "street", "size" => 30 }, "street2" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "street2", "size" => 30 }, "street3" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "street2", "size" => 30 }, "city" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "city", "size" => 30 }, "state" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "state", "size" => 3 }, "zip" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "zip", "size" => 10 }, "nation" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "nation", "size" => 30 }, "natn" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "natn_code", "size" => 5 }, "county" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "county", "size" => 30 }, "atyp" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "atyp", "size" => 2 }, "phone" => { "subname" => "get_addr_pr", "subref" => \&get_addr, "field" => "phone", "size" => 13 }, "street1_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "street", "size" => 30 }, "street2_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "street2", "size" => 30 }, "street3_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "street2", "size" => 30 }, "city_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "city", "size" => 30 }, "state_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "state", "size" => 3 }, "zip_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "zip", "size" => 10 }, "nation_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "nation", "size" => 30 }, "natn_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "natn_code", "size" => 5 }, "county_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "county", "size" => 30 }, "atyp_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "atyp", "size" => 2 }, "phone_lo" => { "subname" => "get_addr_lo", "subref" => \&get_addr, "field" => "phone", "size" => 13 } ); add2hash( $obj_accessor{term_students}, \%id_addr ); add2hash( $obj_accessor{term_faculty}, \%id_addr ); add2hash( $obj_accessor{term_balances}, \%id_addr ); add2hash( $obj_accessor{term_recruits}, \%id_addr ); add2hash( $obj_accessor{term_appls}, $obj_accessor{term_students} ); add2hash( $obj_accessor{term_admits}, $obj_accessor{term_students} ); # ==================================================================== # Dependent Table Definitions (dependent on table definitions above) # ==================================================================== # term_students_id # ---------------- # Note: not used as a table for "queries", but needed as a table defi +nition # for building other tables $obj_accessor{"term_students_id"} = { }; add2hash( $obj_accessor{term_students_id}, $obj_accessor{term_students +} ); # for performance in one-to-many joins, the term_students_id sub retur +ns the id() # fields, unlike the term_students sub $obj_accessor{term_students_id}->{"lname"} = { "subname" => "SELF +", "size" => 60 + }; $obj_accessor{term_students_id}->{"fname"} = { "subname" => "SELF +", "size" => 15 + }; $obj_accessor{term_students_id}->{"mname"} = { "subname" => "SELF +", "size" => 15 + }; $obj_accessor{term_students_id}->{"vnum"} = { "subname" => "SELF +", "size" => 9 + }; $obj_accessor{term_students_id}->{"confidential"} = { "subname" => "S +ELF", "size" => 1 + }; $obj_accessor{term_students_id}->{"deceased"} = { "subname" => "SELF +", "size" => 1 + }; $obj_accessor{term_students_id}->{"citizen"} = { "subname" => "SELF +", "size" => 2 + }; $obj_accessor{term_students_id}->{"gender"} = { "subname" => "SELF +", "size" => 1 + }; $obj_accessor{term_students_id}->{"ethn_code"} = { "subname" => "SELF +", "size" => 2 + }; $obj_accessor{term_students_id}->{"ethnicity"} = { "subname" => "SELF +", "size" => 30 + }; $obj_accessor{term_students_id}->{"birthdate"} = { "subname" => "SELF +", "size" => 10, "datatype" => "dat +e" }; $obj_accessor{term_students_id}->{"age"} = { "subname" => "SELF +", "size" => 3 + }; # stu_schedule # ------------ $obj_accessor{"stu_schedule"} = { }; add2hash( $obj_accessor{stu_schedule}, $obj_accessor{term_students_id} + ); # different population with same fields as term_students_id p +lus # additional fields (SELF refers to &stu_schedule at run time +) # stu_schedule fields not in term_students_id add2hash( $obj_accessor{stu_schedule}, { "crn" => { "subname" => "SELF", "size" => 5 }, "crse_level" => { "subname" => "SELF", "size" => 2 }, "subject" => { "subname" => "SELF", "size" => 4 }, "course" => { "subname" => "SELF", "size" => 5 }, "credit_hrs" => { "subname" => "SELF", "size" => 5, "datatype" => "numeric" }, "add_date" => { "subname" => "SELF", "size" => 10, "datatype" => "date" }, "grade" => { "subname" => "grade", "subref" => \&grade, "field" => "grade", "size" => 6 }, "instructor_lname" => { "subname" => "primary_instructor", "subref" => \&primary_instructor, "field" => "lname", "size" => 60 }, "instructor_fname" => { "subname" => "primary_instructor", "subref" => \&primary_instructor, "field" => "fname", "size" => 15 }, "instructor_mname" => { "subname" => "primary_instructor", "subref" => \&primary_instructor, "field" => "full_mname", "size" => 15 }, "instructor_vnum" => { "subname" => "primary_instructor", "subref" => \&primary_instructor, "field" => "vnum", "size" => 9 } } ); # term_graduates # -------------- $obj_accessor{"term_graduates"} = { }; add2hash( $obj_accessor{term_graduates}, $obj_accessor{term_students} +); delete $obj_accessor{term_graduates}->{resident}; # will replace belo +w add2hash( $obj_accessor{term_graduates}, { "grad_year" => { "subname" => "SELF", "size" => 30 }, "grad_date" => { "subname" => "SELF", "size" => 10, "datatype" => "date" }, "degr_code" => { "subname" => "SELF", "size" => 6 }, "degree" => { "subname" => "SELF", "size" => 30 }, "college" => { "subname" => "SELF", "size" => 30 }, "dept" => { "subname" => "SELF", "size" => 30 }, "honors" => { "subname" => "SELF", "size" => 30 }, "major2" => { "subname" => "SELF", "size" => 30 }, "conc1_1" => { "subname" => "SELF", "size" => 30 }, "conc1_2" => { "subname" => "SELF", "size" => 30 }, "conc1_3" => { "subname" => "SELF", "size" => 30 }, "conc2_1" => { "subname" => "SELF", "size" => 30 }, "conc2_2" => { "subname" => "SELF", "size" => 30 }, "conc2_3" => { "subname" => "SELF", "size" => 30 }, "minor2" => { "subname" => "SELF", "size" => 30 }, "resident" => { "subname" => "first_student", "subref" => \&first_student, "field" => "resident", "size" => 1 } } ); # new_fr # ------ $obj_accessor{"new_fr"} = { }; add2hash( $obj_accessor{new_fr}, $obj_accessor{term_students} ); # new_tr # ------ $obj_accessor{"new_tr"} = { }; add2hash( $obj_accessor{new_tr}, $obj_accessor{term_students} ); # new_fr_tr # --------- $obj_accessor{"new_fr_tr"} = { }; add2hash( $obj_accessor{new_fr_tr}, $obj_accessor{term_students} ); # new_fr_sched # ------ $obj_accessor{"new_fr_sched"} = { }; add2hash( $obj_accessor{new_fr_sched}, $obj_accessor{stu_schedule} ); # new_tr_sched # ------ $obj_accessor{"new_tr_sched"} = { }; add2hash( $obj_accessor{new_tr_sched}, $obj_accessor{stu_schedule} ); # new_fr_tr_sched # --------- $obj_accessor{"new_fr_tr_sched"} = { }; add2hash( $obj_accessor{new_fr_tr_sched}, $obj_accessor{stu_schedule} +); # =================== # Subroutine Params # =================== # driver subs %methods = ( "term_students" => { "parms" => [ "dbh", "term", "level" ] }, "stu_schedule" => { "parms" => [ "dbh", "term", "level" ] }, "term_appls" => { "parms" => [ "dbh", "term", "level" ] }, "term_admits" => { "parms" => [ "dbh", "term", "level" ] }, "term_graduates" => { "parms" => [ "dbh", "term", "level" ] }, "term_balances" => { "parms" => [ "dbh", "term", "dcat_code" ] }, "term_recruits" => { "parms" => [ "dbh", "term", "level" ] }, "term_fac_sched" => { "parms" => [ "dbh", "term" ] }, "term_schedule" => { "parms" => [ "dbh", "term" ] }, "new_fr" => { "parms" => [ "dbh", "term" ] }, "new_tr" => { "parms" => [ "dbh", "term" ] }, "new_fr_tr" => { "parms" => [ "dbh", "term" ] }, "new_fr_sched" => { "parms" => [ "dbh", "term" ] }, "new_tr_sched" => { "parms" => [ "dbh", "term" ] }, "new_fr_tr_sched" => { "parms" => [ "dbh", "term" ] }, # supporting subs "id" => { "parms" => [ "dbh", "\$pidm" ] }, "get_addr_lo" => { "parms" => [ "dbh", "\$pidm", "DO", "LO", "CU" ] }, "get_addr_pr" => { "parms" => [ "dbh", "\$pidm", "PR", "CU", "LO" ] }, "academic_level" => { "parms" => [ "dbh", "\$pidm", "\$level" ] }, "stu_email" => { "parms" => [ "dbh", "\$pidm" ] }, "advisor" => { "parms" => [ "dbh", "\$pidm", "\$term" ] }, "all_gpa_o" => { "parms" => [ "dbh", "\$pidm", "\$level" ] }, "term_hrs" => { "parms" => [ "dbh", "\$pidm", "\$term" ] }, "grade" => { "parms" => [ "dbh", "\$pidm", "\$term", "\$crn" ] }, "class" => { "parms" => [ "dbh", "\$pidm", "\$level" ] }, "enrolled_yn" => { "parms" => [ "dbh", "\$pidm", "\$term" ] }, "student" => { "parms" => [ "dbh", "\$pidm", "\$term" ] }, "first_student" => { "parms" => [ "dbh", "\$pidm" ] }, "hs_gpa" => { "parms" => [ "dbh", "\$pidm" ] }, "SAT" => { "parms" => [ "dbh", "\$pidm" ] }, "ACT" => { "parms" => [ "dbh", "\$pidm" ] }, "fac_sched" => { "parms" => [ "dbh", "\$pidm", "\$term" ] }, "last_tr_coll" => { "parms" => [ "dbh", "\$pidm" ] }, "fr_cohort" => { "parms" => [ "dbh", "\$pidm" ] }, "primary_instructor" => { "parms" => [ "dbh", "\$term", "\$crn" ] }, "section_meet" => { "parms" => [ "dbh", "\$term", "\$crn" ] }, "recr_status" => { "parms" => [ "dbh", "\$term", "\$crn" ] }, "coll_info" => { "parms" => [ "dbh", "\$pidm" ] }, "hs_info" => { "parms" => [ "dbh", "\$hs_code" ] }, "recruit" => { "parms" => [ "dbh", "\$pidm", "\$term", "\$level" ] }, "contact" => { "parms" => [ "dbh", "\$pidm" ] }, "app_decsn" => { "parms" => [ "dbh", "\$pidm", "\$term", "\$appl_no", "12/31/2199" ] } );
, which also maps the table column names to subroutines that get the data.

The sql parser calls the sub get_data() in the following code (See 1st reply for code)

Replies are listed 'Best First'.
Re: Function Dispatcher Table for Virtual Data Warehouse
by jeremyh (Beadle) on Feb 05, 2005 at 00:12 UTC
    must have exceeded a length limit or maybe having multiple readmore/code tags is a problem - here's the code for the dispatcher module:

    get_data() is passed $cols, $tab, $where, $order by the lex/yacc parser.

    The package also has some functions that are used by the lex/yacc parser to parse the query.

    The data retrieval functions are in separate packages.

    The .tables file can represent any data model as long as you have the data retrieval functions for it (we use perl DBI against Oracle, but that is not a requirement).

    Data retrieval functions must return references to arrays of hash references ("records") of the form:

    { "id" => 12345, "lname" => "Jones", "fname" => "Mary, ... }

    if they are "driver functions (return the base information for a population), or they must return hash references ("records") if they are supporting functions (return the "join table" information).

    Only single-table queries against the virtual warehouse are supported.

    For a more complete description see http://www.wou.edu/~hickerj/

Re: Function Dispatcher Table for Virtual Data Warehouse
by jeremyh (Beadle) on Mar 08, 2005 at 22:28 UTC
    I am changing jobs, so if the documentation at

    http://www.wou.edu/~hickerj

    is not available, you will find it at

    http://www.open.org/~hickersf