Results 1 to 9 of 9

Thread: Auto Commiting

  1. #1
    Join Date
    Aug 2003
    Posts
    111

    Unanswered: Auto Commiting

    Hi all,

    I am just wondering if there are any PL/SQL statements which implicitly commits the changes made to the database. I.e. something similar to a auto-commit. I am writing a .Net program which repeatedly calls a oracle procedure within a package. I am using ODP.NET and I do a BeginTransaction at the start of the multiple procedure call. I then do a commit at the end. Despite this, all the procedure calls that have returned without an error were all commited.

    I have tried to run the procedure call through sqlplus (no auto-commit) but it seems to get autocommited as well, for this reason i think it's something to do with my PL/SQL rather than my .NET program.

    Does anyone have any idea why this might happen (i.e. implicit commit)?

    Cheers

    James

  2. #2
    Join Date
    Aug 2003
    Posts
    111
    procedure SPLIT_SHIFT (depots_id_in in number, roster_actual_id_in in number, shift_numbers_actual_id_in in number,
    split_time_in in number, split_location_in in varchar2, timespan_to_depot_in in number, timespan_from_depot_in in number,
    shift_id_out out number)
    as
    i_sna_id number;
    i_ra_id number;
    i_sns_id number;
    i_start_time_depot number;
    i_start_time_road number;
    i_start_road_location number;
    i_finish_road_location number;
    i_finish_time_road number;
    i_finish_time_depot number;
    i_bendy_allow number;
    i_amenity_allow number;
    i_dc_allow number;
    d_shift_date date;
    i_shift_number number;
    i_shift_type_id number;

    i_rsla_id number;
    i_rssa_id number;

    i_new_road_location number := -1;
    i_new_sna_id number := -1;
    begin
    begin
    -- Retrieving table ID for update and insert process.
    select ID, RA_ID, SNS_ID, SHIFT_DATE,
    START_TIME_DEPOT, START_TIME_ROAD, START_ROAD_LOCATION,
    FINISH_ROAD_LOCATION, FINISH_TIME_ROAD, FINISH_TIME_DEPOT,
    BENDY_ALLOW, AMENITY_ALLOW, DC_ALLOW, SHIFT_NUMBER, SHIFT_TYPE_ID
    into i_sna_id, i_ra_id, i_sns_id, d_shift_date,
    i_start_time_depot, i_start_time_road, i_start_road_location,
    i_finish_road_location, i_finish_time_road, i_finish_time_depot,
    i_bendy_allow, i_amenity_allow, i_dc_allow, i_shift_number, i_shift_type_id
    from SHIFT_NUMBERS_ACTUAL
    where shift_numbers_actual.id = shift_numbers_actual_id_in;

    -- select rssa.ID, rssa.RSLA_ID into i_rssa_id, i_rsla_id from ROSTER_SYSTEM_SHIFTS_ACTUAL rssa where SNA_ID = i_sna_id;
    end;

    begin
    select ID into i_new_road_location from LOCATIONS where LOCATION=split_location_in and DEPOTS_ID=depots_id_in;
    exception
    when no_data_found then
    insert into LOCATIONS (DEPOTS_ID, LOCATION) values (depots_id_in, split_location_in) returning ID into i_new_road_location;
    end;

    if i_start_time_depot < i_finish_time_depot then
    if ((split_time_in > i_start_time_road) and (split_time_in < i_finish_time_road)) then
    -- Splitting Algorithm Version 01
    declare
    cursor cMealBreaks is
    select ID, SNA_ID, MEAL_START, MEAL_FINISH, MEAL_LOCATION
    from SHIFT_MEAL_ACTUAL
    where SNA_ID = i_sna_id
    order by MEAL_START;
    i_sma_id_found number := -1;
    i_meal_finish number:= -1;

    n_ret_id number := 40; -- Roster Extension ID 40 = PARTITIONED_SHIFT_COMPONENT
    n_rostered number := 0; -- Not rostered

    n_start_time_depot number;
    n_start_time_road number;
    n_start_road_location number;
    n_finish_road_location number;
    n_finish_time_road number;
    n_finish_time_depot number;
    begin
    for vMealBreak in cMealBreaks loop
    if i_sma_id_found = -1 then
    if split_time_in < vMealBreak.MEAL_START then
    -- split before this meal break (split_time_in < vMealBreak.MEAL_START)
    i_sma_id_found := vMealBreak.ID;

    n_finish_time_road := split_time_in;
    n_finish_time_depot := split_time_in + timespan_to_depot_in;
    n_finish_road_location := i_new_road_location;
    update SHIFT_NUMBERS_ACTUAL
    set FINISH_ROAD_LOCATION = n_finish_road_location,
    FINISH_TIME_ROAD = n_finish_time_road,
    FINISH_TIME_DEPOT = n_finish_time_depot
    where ID = shift_numbers_actual_id_in;

    n_start_time_depot := split_time_in - timespan_from_depot_in;
    n_start_time_road := split_time_in;
    n_start_road_location := i_new_road_location; -- start road location is the split location
    n_finish_road_location := i_finish_road_location;
    n_finish_time_road := i_finish_time_road;
    n_finish_time_depot := i_finish_time_depot;

    insert into SHIFT_NUMBERS_ACTUAL
    (SNA_ID, SNS_ID, RA_ID, ROSTERED, RET_ID, SHIFT_TYPE_ID,
    BENDY_ALLOW, AMENITY_ALLOW, DC_ALLOW, SHIFT_DATE, SHIFT_NUMBER,
    START_TIME_DEPOT, START_TIME_ROAD, START_ROAD_LOCATION,
    FINISH_ROAD_LOCATION, FINISH_TIME_ROAD, FINISH_TIME_DEPOT)
    values
    (shift_numbers_actual_id_in, i_sns_id, i_ra_id, n_rostered, n_ret_id, i_shift_type_id,
    i_bendy_allow, i_amenity_allow, i_dc_allow, d_shift_date, i_shift_number,
    n_start_time_depot, n_start_time_road, n_start_road_location,
    n_finish_road_location, n_finish_time_road, n_finish_time_depot)
    returning ID into i_new_sna_id;

    update SHIFT_MEAL_ACTUAL
    set SNA_ID = i_new_sna_id
    where ID = vMealBreak.ID;

    shift_id_out := i_new_sna_id;
    else
    if split_time_in < vMealBreak.MEAL_FINISH then
    -- sick between this meal break (time_off_road < vMealBreak.MEAL_START, time_off_road < vMealBreak.MEAL_FINISH)
    i_sma_id_found := vMealBreak.ID;

    -- 1. shorten original shift to reflect splitting
    n_finish_time_road := split_time_in;
    n_finish_time_depot := split_time_in + timespan_to_depot_in;
    n_finish_road_location := i_new_road_location;
    update SHIFT_NUMBERS_ACTUAL
    set FINISH_ROAD_LOCATION = n_finish_road_location,
    FINISH_TIME_ROAD = n_finish_time_road,
    FINISH_TIME_DEPOT = n_finish_time_depot
    where ID = shift_numbers_actual_id_in;

    -- 2. insert new shift (representing the shift that gets split off)
    n_start_time_depot := vMealBreak.MEAL_FINISH - timespan_from_depot_in;
    n_start_time_road := vMealBreak.MEAL_FINISH;
    n_start_road_location := i_new_road_location;
    n_finish_road_location := i_finish_road_location;
    n_finish_time_road := i_finish_time_road;
    n_finish_time_depot := i_finish_time_depot;

    insert into SHIFT_NUMBERS_ACTUAL
    (SNA_ID, SNS_ID, RA_ID, ROSTERED, RET_ID, SHIFT_TYPE_ID,
    BENDY_ALLOW, AMENITY_ALLOW, DC_ALLOW, SHIFT_DATE, SHIFT_NUMBER,
    START_TIME_DEPOT, START_TIME_ROAD, START_ROAD_LOCATION,
    FINISH_ROAD_LOCATION, FINISH_TIME_ROAD, FINISH_TIME_DEPOT)
    values
    (shift_numbers_actual_id_in, i_sns_id, i_ra_id, n_rostered, n_ret_id, i_shift_type_id,
    i_bendy_allow, i_amenity_allow, i_dc_allow, d_shift_date, i_shift_number,
    n_start_time_depot, n_start_time_road, n_start_road_location,
    n_finish_road_location, n_finish_time_road, n_finish_time_depot)
    returning ID into i_new_sna_id;

    -- 3. shorten meal break to reflect changes
    update SHIFT_MEAL_ACTUAL
    set MEAL_FINISH=( split_time_in )
    where ID = vMealBreak.ID;

    -- 4. no new meal break is created for the 2nd portion of the splitted shift
    -- this is because if a shift starts with a meal break,
    -- the start time of the shift is pushed back (saves money another word
    -- see step 2 above (the if statement)

    shift_id_out := i_new_sna_id;
    end if;
    end if;
    else
    -- 1. Allocate the rest of the meal breaks to the 2nd portion of the splitted shift
    update SHIFT_MEAL_ACTUAL
    set SNA_ID = i_new_sna_id
    where ID = vMealBreak.ID;
    end if;
    i_meal_finish := vMealBreak.MEAL_FINISH;
    end loop;

    if split_time_in > i_meal_finish or i_meal_finish = -1 then
    -- this condition identifies the case
    -- 1. when there is no meal and (i_meal_finish = -1, this condition can be omitted but it is included for clarity)
    -- 2. when sick occurs after all meal breaks (time_off_road > i_meal_finish)

    n_finish_time_road := split_time_in;
    n_finish_time_depot := split_time_in + timespan_to_depot_in;
    n_finish_road_location := i_new_road_location;
    update SHIFT_NUMBERS_ACTUAL
    set FINISH_ROAD_LOCATION = n_finish_road_location,
    FINISH_TIME_ROAD = n_finish_time_road,
    FINISH_TIME_DEPOT = n_finish_time_depot
    where ID = shift_numbers_actual_id_in;

    n_start_time_depot := split_time_in - timespan_from_depot_in;
    n_start_time_road := split_time_in;
    n_start_road_location := i_new_road_location; -- start road location is the split location
    n_finish_road_location := i_finish_road_location;
    n_finish_time_road := i_finish_time_road;
    n_finish_time_depot := i_finish_time_depot;

    insert into SHIFT_NUMBERS_ACTUAL
    (SNA_ID, SNS_ID, RA_ID, ROSTERED, RET_ID, SHIFT_TYPE_ID,
    BENDY_ALLOW, AMENITY_ALLOW, DC_ALLOW, SHIFT_DATE, SHIFT_NUMBER,
    START_TIME_DEPOT, START_TIME_ROAD, START_ROAD_LOCATION,
    FINISH_ROAD_LOCATION, FINISH_TIME_ROAD, FINISH_TIME_DEPOT)
    values
    (shift_numbers_actual_id_in, i_sns_id, i_ra_id, n_rostered, n_ret_id, i_shift_type_id,
    i_bendy_allow, i_amenity_allow, i_dc_allow, d_shift_date, i_shift_number,
    n_start_time_depot, n_start_time_road, n_start_road_location,
    n_finish_road_location, n_finish_time_road, n_finish_time_depot)
    returning ID into i_new_sna_id;

    shift_id_out := i_new_sna_id;
    end if;
    end;
    else
    raise_application_error (-20000, 'Invalid Split Information Supplied: Split time found outside shift duration (Same Day)'
    || chr(10) || 'Split Time: ' || split_time_in || ' minutes'
    || chr(10) || 'Shift (Actual) ID: ' || i_sna_id
    || chr(10) || 'Shift Start Time Depot: ' || i_start_time_depot || ' minutes'
    || chr(10) || 'Shift Start Time Road: ' || i_start_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Road: ' || i_finish_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Depot: ' || i_finish_time_depot || ' minutes'
    || chr(10) || 'Shift Date: ' || TO_CHAR(d_shift_date, 'DD MON YYYY'));
    end if;

  3. #3
    Join Date
    Aug 2003
    Posts
    111
    elsif i_start_time_depot > i_finish_time_depot then -- shift spans across two days
    -- Splitting Algorithm Version 02
    declare
    cursor cMealBreaks is
    select ID, SNA_ID, MEAL_START, MEAL_FINISH, MEAL_LOCATION
    from SHIFT_MEAL_ACTUAL
    where SNA_ID = i_sna_id
    order by MEAL_START;

    n_ret_id number := 40; -- Roster Extension ID 40 = PARTITIONED_SHIFT_COMPONENT
    n_rostered number := 0; -- Not rostered

    n_start_time_depot number;
    n_start_time_road number;
    n_start_road_location number;
    n_finish_road_location number;
    n_finish_time_road number;
    n_finish_time_depot number;
    n_shift_date date;
    n_ra_id number;
    begin

    /**************************
    * SPLITTING SHIFT
    **************************/

    -- 1. update original shift
    n_finish_time_road := split_time_in;
    n_finish_time_depot := Mod((split_time_in + timespan_to_depot_in), 1440);
    n_finish_road_location := i_new_road_location;
    update SHIFT_NUMBERS_ACTUAL
    set FINISH_ROAD_LOCATION = n_finish_road_location,
    FINISH_TIME_ROAD = n_finish_time_road,
    FINISH_TIME_DEPOT = n_finish_time_depot
    where ID = shift_numbers_actual_id_in;

    -- 2. create a new shift (needs to be updated to reflect meal break information)
    n_start_time_depot := Mod((split_time_in - timespan_from_depot_in + 1440), 1440);
    n_start_time_road := split_time_in;
    n_start_road_location := i_new_road_location;
    n_finish_road_location := i_finish_road_location;
    n_finish_time_road := i_finish_time_road;
    n_finish_time_depot := i_finish_time_depot;
    n_ra_id := i_ra_id;

    if (split_time_in > i_start_time_depot) then
    n_shift_date := d_shift_date;
    elsif (split_time_in < i_finish_time_depot) then
    n_shift_date := d_shift_date + 1; -- the splitted shift crosses over to the next day.
    else
    raise_application_error (-20000, 'Invalid Split Information Supplied: Split time found outside shift duration (Same Day)'
    || chr(10) || 'Split Time: ' || split_time_in || ' minutes'
    || chr(10) || 'Shift (Actual) ID: ' || i_sna_id
    || chr(10) || 'Shift Start Time Depot: ' || i_start_time_depot || ' minutes'
    || chr(10) || 'Shift Start Time Road: ' || i_start_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Road: ' || i_finish_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Depot: ' || i_finish_time_depot || ' minutes'
    || chr(10) || 'Shift Date: ' || TO_CHAR(d_shift_date, 'DD MON YYYY'));
    end if;

    -- the following code handles a rare situation where
    -- splitted shift also crosses over to the following roster
    declare
    d_temp_start_date date;
    i_temp_ra_id number;
    begin
    select START_DATE
    into d_temp_start_date
    from ROSTER_ACTUAL
    where ID = i_ra_id;
    if (n_shift_date > d_temp_start_date + 6) then
    begin
    select ID
    into i_temp_ra_id
    from ROSTER_ACTUAL
    where DEPOTS_ID = depots_id_in
    and START_DATE = (d_temp_start_date + 7);
    exception
    when no_data_found then
    raise_application_error(-20000, 'SPLIT_SHIFT operation terminated due to the following error'
    || chr(10) || 'The resulting splitted shift crosses over to the next running roster, but no running roster has been found for the following week.' || chr(10)
    || chr(10) || 'SPLIT_SHIFT Details:'
    || chr(10) || 'Split Time: ' || split_time_in || ' minutes'
    || chr(10) || 'Shift (Actual) ID: ' || i_sna_id
    || chr(10) || 'Shift Start Time Depot: ' || i_start_time_depot || ' minutes'
    || chr(10) || 'Shift Start Time Road: ' || i_start_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Road: ' || i_finish_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Depot: ' || i_finish_time_depot || ' minutes'
    || chr(10) || 'Shift Date: ' || TO_CHAR(d_shift_date, 'DD MON YYYY'));
    end;
    n_ra_id := i_temp_ra_id;
    end if;
    end;


    insert into SHIFT_NUMBERS_ACTUAL
    (SNA_ID, SNS_ID, RA_ID, ROSTERED, RET_ID, SHIFT_TYPE_ID,
    BENDY_ALLOW, AMENITY_ALLOW, DC_ALLOW, SHIFT_DATE, SHIFT_NUMBER,
    START_TIME_DEPOT, START_TIME_ROAD, START_ROAD_LOCATION,
    FINISH_ROAD_LOCATION, FINISH_TIME_ROAD, FINISH_TIME_DEPOT)
    values
    (shift_numbers_actual_id_in, i_sns_id, n_ra_id, n_rostered, n_ret_id, i_shift_type_id,
    i_bendy_allow, i_amenity_allow, i_dc_allow, n_shift_date, i_shift_number,
    n_start_time_depot, n_start_time_road, n_start_road_location,
    n_finish_road_location, n_finish_time_road, n_finish_time_depot)
    returning ID into i_new_sna_id;

    shift_id_out := i_new_sna_id;

    /**************************
    * MEALBREAK UPDATE
    **************************/

    for vMealBreak in cMealBreaks loop
    -- Alternative Implementation
    -- The following if statements accounts for all possible valid cases of
    -- MEAL BREAKS that can be found within a shift that spans across 2 days.
    if ((vMealBreak.MEAL_START > i_start_time_depot) and (vMealBreak.MEAL_FINISH > i_start_time_depot)) then
    -- meal break is before midnight
    if ((split_time_in > i_start_time_depot) and (split_time_in < vMealBreak.MEAL_START)) then
    -- 1. split before meal break
    -- update meal with new sna_id
    update SHIFT_MEAL_ACTUAL
    set SNA_ID = i_new_sna_id
    where ID = vMealBreak.ID;
    elsif ((split_time_in > vMealBreak.MEAL_START) and (split_time_in < vMealBreak.MEAL_FINISH)) then
    -- 2. split in meal break
    -- update meal with new MEAL_FINISH (new shift should start after meal break)
    update SHIFT_MEAL_ACTUAL
    set MEAL_FINISH=( split_time_in )
    where ID = vMealBreak.ID;
    -- update shift with new START_DEPOT_TIME and START_ROAD_TIME
    n_start_time_depot := mod ((vMealBreak.MEAL_FINISH - timespan_from_depot_in + 1440), 1440);
    n_start_time_road := vMealBreak.MEAL_FINISH;
    update SHIFT_NUMBERS_ACTUAL
    set START_TIME_DEPOT = n_start_time_depot,
    START_TIME_ROAD = n_start_time_road
    where ID = i_new_sna_id;
    elsif ((split_time_in > vMealBreak.MEAL_FINISH) or (split_time_in < i_finish_time_depot)) then
    -- 3. split after meal break
    -- nothing to update
    null;
    end if;
    elsif ((vMealBreak.MEAL_START > i_start_time_depot) and (vMealBreak.MEAL_FINISH < i_finish_time_depot)) then
    -- meal break spans across 2 days
    if ((split_time_in > i_start_time_depot) and (split_time_in < vMealBreak.MEAL_START)) then
    -- 1. split before meal break
    -- update meal with new sna_id
    update SHIFT_MEAL_ACTUAL
    set SNA_ID = i_new_sna_id
    where ID = vMealBreak.ID;
    elsif (((split_time_in > vMealBreak.MEAL_START) and (split_time_in > vMealBreak.MEAL_FINISH))
    or ((split_time_in < vMealBreak.MEAL_START) and (split_time_in < vMealBreak.MEAL_FINISH))) then
    -- 2. split in meal break
    -- update meal with new MEAL_FINISH
    update SHIFT_MEAL_ACTUAL
    set MEAL_FINISH=( split_time_in )
    where ID = vMealBreak.ID;
    -- update shift with new START_DEPOT_TIME and START_ROAD_TIME
    n_start_time_depot := mod ((vMealBreak.MEAL_FINISH - timespan_from_depot_in + 1440), 1440);
    n_start_time_road := vMealBreak.MEAL_FINISH;
    update SHIFT_NUMBERS_ACTUAL
    set START_TIME_DEPOT = n_start_time_depot,
    START_TIME_ROAD = n_start_time_road
    where ID = i_new_sna_id;
    elsif ((split_time_in > vMealBreak.MEAL_FINISH) and (split_time_in < i_finish_time_depot)) then
    -- 3. split after meal break
    -- nothing to update
    null;
    end if;
    elsif ((vMealBreak.MEAL_START < i_finish_time_depot) and (vMealBreak.MEAL_FINISH < i_finish_time_depot)) then
    -- meal break is after midnight
    if ((split_time_in > i_start_time_depot) or (split_time_in < vMealBreak.MEAL_START)) then
    -- 1. split before meal break
    -- update meal with new sna_id
    update SHIFT_MEAL_ACTUAL
    set SNA_ID = i_new_sna_id
    where ID = vMealBreak.ID;

  4. #4
    Join Date
    Aug 2003
    Posts
    111
    elsif ((split_time_in > vMealBreak.MEAL_START) and (split_time_in < vMealBreak.MEAL_FINISH)) then
    -- 2. split in meal break
    -- update meal with new MEAL_FINISH
    update SHIFT_MEAL_ACTUAL
    set MEAL_FINISH=( split_time_in )
    where ID = vMealBreak.ID;
    -- update shift with new START_DEPOT_TIME and START_ROAD_TIME
    n_start_time_depot := mod ((vMealBreak.MEAL_FINISH - timespan_from_depot_in + 1440), 1440);
    n_start_time_road := vMealBreak.MEAL_FINISH;
    update SHIFT_NUMBERS_ACTUAL
    set START_TIME_DEPOT = n_start_time_depot,
    START_TIME_ROAD = n_start_time_road
    where ID = i_new_sna_id;
    elsif ((split_time_in > vMealBreak.MEAL_FINISH) and (split_time_in < i_finish_time_depot)) then
    -- 3. split after meal break
    -- nothing to update
    null;
    end if;
    end if;
    end loop;
    end;
    else
    raise_application_error (-20000, 'SPLIT_SHIFT is not possible: START_TIME_DEPOT = FINISH_TIME_DEPOT.' || chr(10)
    || chr(10) || 'Depot ID: ' || depots_id_in
    || chr(10) || 'Roster (Actual) ID: ' || roster_actual_id_in
    || chr(10) || 'Shift (Actual) ID: ' || i_sna_id
    || chr(10) || 'Shift Start Time Depot: ' || i_start_time_depot || ' minutes'
    || chr(10) || 'Shift Start Time Road: ' || i_start_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Road: ' || i_finish_time_road || ' minutes'
    || chr(10) || 'Shift Finish Time Depot: ' || i_finish_time_depot || ' minutes'
    || chr(10) || 'Shift Date: ' || TO_CHAR(d_shift_date, 'DD MON YYYY'));
    end if;
    end;

  5. #5
    Join Date
    Aug 2003
    Posts
    111
    Above is the chunk of code that i call repeatedly and which seem to commit implicitly. Sorry for the length of the code, you don't have to read through it, all I want to know is whether there are PL/SQL statements which implictly commits database changes. I included the code for completeness.

    Thanx

    James

  6. #6
    Join Date
    Jan 2004
    Location
    Singapore
    Posts
    89
    Originally posted by nano_electronix
    Above is the chunk of code that i call repeatedly and which seem to commit implicitly. Sorry for the length of the code, you don't have to read through it, all I want to know is whether there are PL/SQL statements which implictly commits database changes. I included the code for completeness.

    Thanx

    James
    I never tried whether this works, but heard of something called set autocommit off. Have u tried this?
    Thanks and Regards,

    Praveen Pulikunnu

  7. #7
    Join Date
    Sep 2002
    Location
    UK
    Posts
    5,171
    Provided Answers: 1
    If you executed any DDL via your PL/SQL (like EXECUTE IMMEDIATE 'DROP TABLE foo') this would automatically commit everything done before it. However, I don't see anything like that in your code.

  8. #8
    Join Date
    Aug 2003
    Posts
    111
    Originally posted by praveenpr
    I never tried whether this works, but heard of something called set autocommit off. Have u tried this?
    I think this set autocommit off option that you are talking about is a sqlplus command right? my sqlplus plus session is by default set to autocommit off.


  9. #9
    Join Date
    Aug 2003
    Posts
    111
    Originally posted by andrewst
    If you executed any DDL via your PL/SQL (like EXECUTE IMMEDIATE 'DROP TABLE foo') this would automatically commit everything done before it. However, I don't see anything like that in your code.
    Thanks, I will have to look more carefully into my code, but yes that's the answer that I was looking for.

    Thank you

    James

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •