How to data-model dynamic open/close times for booking a room - datamodel

this is my first post. I have been searching for the best way to do this but have not had much success so I decided to post here.
I have a database model that is going to be used to book rooms in a complex. These rooms need to have open and close times to determine when they can be booked. For example, one room may be open from 8am to 10pm but another might be open from 10am to 5pm etc.
One of the requirements, and the part I'm stuck on, is that the open/close times for rooms needs to changed based on a time period similar to a "season" but this time period is manually set by an admin unlike a season.
So, from Jan-11 to March-28, a specific room may to open from 10am to 5pm but from March-29 to July-17 it may be open from 8am to 7pm.
I'm guessing that I need another table or two to store the "time periods" as well as the open/close time of the room during those periods.
Can anyone point me in the right direction or show me an example?
Thanks.

It highly depends on logic of your application, but in the simplest case you can save it inside additional table of the following structure:
room_id INT
period_from DATE
period_to DATE
open_from INT
open_to INT
You can select open time for a room on particular day using:
SELECT open_from, open_to
FROM intervals
WHERE room_id = 4 AND period_from > '2015-08-19' AND period_to < '2015-08-19'
NOTE When you add new period, you should validate, that time periods don't intersect for a given room.

Related

Query to prevent booking overlap

I'm doing an app in Apex Oracle and trying to find a query that could prevent people from booking a room already booked. I managed to find a query that can prevent picking a date that starts or ends in between the booking time but I can't find how to prevent overlaping. By that I mean if someone books a conference room feb 2nd to feb 5th, someone can book the same room from feb 1st to feb 7th. That is what I'm trying to prevent. Thanks for the help!
Here's my first query
SELECT RES_ID_LOC FROM WER_RES
WHERE (CAST(RES_DATE_ARRIVE AS DATE) < CAST(TRY_RESERVE_START_DATE AS DATE) OR CAST(RES_DATE_DEPART AS DATE)
CAST(TRY_RESERVE_START_DATE AS DATE))
AND (CAST(RES_DATE_ARRIVE AS DATE) < CAST(TRY_RESERVE_END_DATE AS DATE) OR CAST(RES_DATE_DEPART AS DATE) > CAST(TRY_RESERVE_END_DATE AS DATE))
The main issue you'll have here is concurrency, namely (in chronological order)
User 1
runs overlap check query, see Room 5 is free, and inserts a row to book it
User 2
runs overlap check query, see Room 5 is free, and inserts a row to book it
User 1
commits
User 2
commits
and voila! You have a data corruption, even though the code all ran as you expected.
To avoid this, you'll need some way to lock a resource that multiple might want to book. Thus lets say you have a ROOMS table (list of available rooms) and a BOOKINGS table which is a child of ROOM.
Then your logic will need be something like:
select from ROOM where ROOM_NO = :selected_room for update;
This gives someone exclusive access to the room to check for bookings.
Now you can run your overlap check on that room against the BOOKINGS table. If that passes, then you insert your booking and commit the change to release the lock on the ROOMS row.
As an aside, take care with simply casting strings to dates, because you're at the whim of the format mask of the item matching that default of the database. Better to explicitly use a known format mask and TO_DATE

How to calculate the current value of depreciated asset?

I'm aware of various depreciation formulas in google sheets, but to me it seems like non of them provide and cumulative value. So if I wanted to calculate the current value of a car bought 6 months ago, I'd have to have multiple rows calculating depreciation per month, and then I'd have to sum the depreciation over months (cells). Is there a way to put everything in one cell? Example:
https://docs.google.com/spreadsheets/d/1u3py5XG9IPBAMQXGmG0q-kyg60fxJ72Gy8C90Za1FTg
Columns A:F is working fine, but I want to be able to be able to have a list of multiple assets with todays (depriciated) value, like in columns H:P .
Any idea how I could achieve that?
Even though this is very brief, I want to record the comment that helped answer this question.
Will the VDB function work for you?
You enter:
VDB(cost, salvage, life, start_period, end_period, [factor], [no_switch]).
So Purchase Price - VDB(...) is the current asset value, after a specific period of time, of the asset's lifespan.
Specify start_period as zero, and end period as the number of years (or fractions) that have passed, and the result is the total depreciation over that time period. It defaults to give a DDB (Double Declining Balance depreciation) answer, but the rate (factor) can be modified. Hope this helps. I'm sure there are other options

Camel + CassandraQL : Process a table without putting all in memory

Goal: read a big Cassandra table, process line by line in parallel
Constraints:
not all rows in memory
no Spark, we have to use Camel
One shot, no need polling the table
I did a first working version with CassandraQL but this Component seems to be limited to one query with all in memory, I did not find mechanics like fetSize/fetchMoreResult. I looked CassandraProducer class, PollingConsumerPollingStrategy, ResultSetConversionStrategy... See nothing.
Could it be possible to read a table by chunks of 1000 elements for example, each chunk would generate an exchange lately split in different threads ?
I think that maybe the ProducerTemplate injecting first exchanges in the route could be the answer. But I don't undertand how I could manage the production exchange rate to avoid to have too many rows in memory (to do so, we would need for example to check the size of the next blocking queue, if more than X no consumed elements, wait before producing more messages).
Maybe there are other options to do something like this ?
Maybe I did not see the magic parameter in CassandraQL ?
Maybe we can override some parts of CassandraQL ?
Thank you
This is not going to be answer to be a your question but hope to kick off some discussion. But as someone learning Cassandra and spending bit of time, it made me thinking. And mainly targets fetSize/fetchMoreResult part of the question
First of all, two of your constraints are contradicting
Not all rows in memory
I don't want all them fetched at once
One shot, no need polling the partition
I don't want to go back to db more than once.
Unless what you actually you meant is
Not all rows in memory
I don't want all them fetched at once
You can go back to partition many times, as long as you go back straight to where you left it last time.
As long as the time it takes for the first page is same as time it takes for the second page. And the time it takes for the 19th Page is same as the time it takes for the 20th page.
i.e Not starting from the first row
So I am going to assume that what you meant is Second Scenario and go with it.
Queries for Cassandra are going to satisfy the following two:
They are going to have a restriction on clustering columns
They are already ordered by clustering columns
Now Consider the following table
department(partition key), firstName(clustering_key), personId(clustering_key), lastname, etc as normal cols
First query
select department, firstName, lastname, etc
from person
where department = 'depart1`
order by firstName ASC
limit 25;
Second query (lets say last record in the page had userId=25 and firstName=kavi)
select department, firstName, lastname, etc
from person
where department = 'depart1` and firstName='kavi' and userId > 25
order by firstName ASC
limit 25;
As you can see, we can easily construct a Cassandra query that brings each chunk with certain size in constant time.
Now back to integration framework
I remember this concept called watermark in mule where the endpoint can store and remember so that they can start from there next time. In this case, value of userId and firstName of the last record of the last page is the watermark. So they can issue the second. I am sure we should be able to do the same with camel
I hope I have convinced that polling is not an issue where each chunk is retrieved in constant time

Separate dated lines into beginning and end of month (LibreOffice)

Given a list of items which have a date as one field, how can I separate one set which have a date in the first few days of the month from those which have a date in the last few days?
The items are gas bills, generally one per month, in a bank statement which relate to each of two separate buildings and need to go into two separate accounts. They were imported from a CSV file.
In practice, the number of lines involved is small, so I've just done it by hand, but the question of how to do it by formula and sort occurred to me, and I neither have nor found an answer.
I hope it is a slightly interesting question.
The function is simply called DAY. You can find it by clicking on the Function Wizard toolbar icon and looking under the Date&Time category.
For example, in cell B1 enter a formula like =DAY(A1) and fill down. Then go to Data -> Sort.

Can I generate the number of business days in a month in Visual Studio?

I have a report that takes sales data from a few tables. I want to add a field that will divide the total sales for the given month by the total number of business days in that same month. Is there a way I can calculate that in an expression? Do I need to create a new table in the database specifically for months and their number of business days? How should I go about this?
Thank you
Intuitively, I would say that you need a simple function and a table.
The table is to host the exceptions like Independence day, labor day, etc.
The function will get two parameters: Month and Year (I'm not providing any sample code since you haven't specified which language you are using).
It will then build a date as yyyy-mm-01 (meaning, first day of the month). If will then loop from 2 to 31 and:
Create a new date by adding the index of the loop to the initial date,
Check if the resulting date is still within the month,
Check if it is a working or not working day (e.g. Sunday),
Check if it is found within the table of exceptions.
If the created date passes all the above tests, you add 1 to the counter.
Though it might look complex, it is not and it will provide you the correct answer regardless of the month (e.g. Feb.) and the year (leap or not).

Resources