IMAP UID FETCH Command - Return two sequence numbers by one UID request - email

In very rare cases server returns a second sequence number.
Example log:
C: A0020 UID FETCH 304244 (BODY[HEADER.FIELDS (SUBJECT FROM TO CC REPLYTO MESSAGEID DATE SIZE REFERENCES)] UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE RFC822.HEADER)
S: * 9 FETCH (BODY[HEADER.FIELDS (SUBJECT FROM TO CC REPLYTO MESSAGEID DATE SIZE REFERENCES)] {262}
S: Date: Thu, 29 Dec 2022 00:00:00 +0000\r\nFrom: Name <email#domain.com>\r\nSubject: Subject\r\nTo: <email#domain.com>\r\nCC:\r\n\r\n
S: UID 304244 FLAGS (\\Seen) INTERNALDATE \"29-Dec-2022 01:00:00 +0100\" RFC822.SIZE 226713 ENVELOPE (ENVELOPE DATA) RFC822.HEADER {7754}
S: MIME-Version: 1.0\r\nReceived: from ... email data
S: FLAGS (\\Seen))
S: * 11 FETCH (FLAGS (\\Seen \\Deleted))
S: A0020 OK FETCH completed.
Client request UID FETCH by UID "304244". The server responded that the email is "9" sequence number. At the end before "OK FETCH completed." the server returns another sequence number "11" with information about the flags.
I tried to find in https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5 , https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8 and elsewhere some information on such responses from the server, but found nothing. Does anyone know why the server in the "UID FETCH" command response returns another sequence number with information about the flags and what it can mean?
UPDATE:
Today I have got this case:
C: A0051 UID FETCH 305421 (BODY[HEADER.FIELDS (SUBJECT FROM TO CC REPLYTO MESSAGEID DATE SIZE REFERENCES)] UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE RFC822.HEADER)
S: * 40 FETCH (BODY[HEADER.FIELDS (SUBJECT FROM TO CC REPLYTO MESSAGEID DATE SIZE REFERENCES)] {209}
S: To: email#domain.com\r\nSubject: Subject\r\nDate: Tue, 03 Jan 2023 00:07:15 +0200\r\nFrom: <email#domain.com>\r\n\r\n
S: UID 305421 FLAGS (\\Seen) INTERNALDATE \"02-Jan-2023 23:07:20 +0100\" RFC822.SIZE 158940 ENVELOPE (ENVELOPE DATA) RFC822.HEADER {8278}
S: MIME-Version: 1.0\r\nReceived: from ... email data
S: FLAGS (\\Seen))
S: * 3 FETCH (FLAGS (\\Seen \\Deleted))
S: * 4 FETCH (FLAGS (\\Seen \\Deleted))
S: * 5 FETCH (FLAGS (\\Seen \\Deleted))
S: * 6 FETCH (FLAGS (\\Seen \\Deleted))
S: * 7 FETCH (FLAGS (\\Seen \\Deleted))
S: * 8 FETCH (FLAGS (\\Seen \\Deleted))
S: A0051 OK FETCH completed.
So, if I understood the answer below correctly. While the server run "UID FETCH" the email from the server, someone in another session change this and other emails. In begin of "UID FETCH" the sequence number was "40". But during command execution the sequence number changed several times: 40 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8. That is why the server sends me these "* number FETCH (FLAGS ...)" lines. Did I understand correctly?

What you want is described in IMAP-speak as: Your FETCH command directs the server to send an untagged FETCH command before the server concludes processing the FETCH command, and return a tagged response with the result (usually just OK).
Note the verb directs. Other things can also direct the server to send untagged responses, even at the same time as you direct it. For example, when new mail arrives, that directs the server to send an untagged EXISTS response as soon as possible.
Your example is a bit strange, but the server is allowed to do it.
The simplest way to deal with it is to maintain a cache of messages clientside, update the relevant message in the cache whenever you get a FETCH response, and when you receive a tagged OK, you can trust that the information you wanted is now present in the cache.
Make sure to test what happens if a message is deleted just as you request it. The server's untagged responses should cause your cache to contain something like 'this message has been deleted'.

Related

sql code to compare previous row in a series

So I have a table that has an ArticleID (GUID), RevisionNumber (integer), and StatusCode (text).
An Article can have any number of revisions but each time a new revision is created, the StatusCode of the previous revision should be "Revised" and the newest revision's StatusCode could be "Active" or "Draft" or "Canceled". However the data is messed up and I need to identify which records (out of 100's of thousands) do not have the correct status.
Sample data:
Article ID RevisionNumber StatusCode
========== ============== ==========
xx-xxxx-xx 7 Active
xx-xxxx-xx 6 Revised
xx-xxxx-xx 5 Active
xx-xxxx-xx 4 Draft
xx-xxxx-xx 3 Revised
xx-xxxx-xx 2 Active
xx-xxxx-xx 1 Revised
xx-xxxx-xx 0 Revised
xx-yyyy-yy 1 Active
xx-yyyy-yy 0 Active
In the above scenario, I would need to know that xx-xxxx-xx Revision 5, 4, and 2 are not the proper status and xx-yyyy-yy Revision 0 is incorrect. How could I get this information from a sql query using sql server 2012?
To identify any revisions that are not "Revised" if there is a higher number revision.
Then it seems just a matter of knowing what the latest revision is.
A MAX OVER can do that.
SELECT ArticleID, RevisionNumber, StatusCode
FROM
(
SELECT ArticleID, RevisionNumber, StatusCode
, MAX(RevisionNumber) OVER (PARTITION BY ArticleID) AS MaxRevisionNumber
FROM YourTable
) q
WHERE (RevisionNumber < MaxRevisionNumber AND StatusCode != 'Revised')
You can do this with a left join -- for each record we look for one with a greater revision -- like this:
SELECT *
FROM table_you_did_not_name base
LEFT JOIN table_you_did_not_name next ON base.ArticleID = next.ArticleID and base.revisionnumber = next.revisionnumber + 1
WHERE status <> 'Revised' and next.ArticleID is not null

Find string in a large text with postgresql

I have a column called data in a PostgreSQL table that contains the following:
-----BEGIN HEADER-----
TYPE = PKCS#10
SERIAL = xxxxx
NOTBEFORE = Thu Sep 9 12:37:43 2010 UTC
LOA = 10
ROLE = xxxxx
RA = xxxxx
REQUEST_AUTH_USERID = CN=xxxxxxx
SCEP_TID = xxxxx
ARCHIVED_AFTER = Mon Nov 30 17:41:40 2015
_AFTER = Tue Jan 26 09:26:14 2016
-----END HEADER-----
-----BEGIN CERTIFICATE REQUEST-----
MIICWTCCAUECAQAwFjEUMBIGA1UEAwwLQ09QUzAwMDEzMDAwggEiMA0GCSqGSIb3
.
.
.
.
bV0eG4rlMOgTPv6mqb9HHKFqi3dsDzZKfXyoAsLOyOkj+AWXmAfXG8enT4uqBJJf
AsrUuJyTwzvmfdcEgYxokI6FU/nAjgQpmLkuVrE=
-----END CERTIFICATE REQUEST-----
As we want to move to a different application, I only need the part beginning with -----BEGIN CERTIFICATE REQUEST-----.
I tried to extract this string with substring and position in a SQL query but even if I try to find the possition of this string with:
SELECT position('-----BEGIN CERTIFICATE REQUEST-----' in (SELECT data from openca2.request where req_key = 3874))
I get a NULL value. I only can find examples where a part of a single string is extracted.
I don't know if the spaces are a problem. The part within the beginning and end header are not always the same.
Can this be done with a SQL query?
SELECT substr(
data,
position('-----BEGIN CERTIFICATE REQUEST-----' IN data)
)
FROM openca2.request
WHERE req_key = 3874;
How about:
SELECT split_part(data, '-----BEGIN CERTIFICATE REQUEST-----', 2)
FROM openca2.request
WHERE req_key = 3874;
If you want to keep '-----BEGIN CERTIFICATE REQUEST-----' then use '-----END HEADER-----' instead.
Thanks for your response. Both solutions are working.
I just have notices when I tried your queries that I was searching for the wrong req_key ..... and where I have the right req_key my solution works also
SELECT substring(data, position('-----BEGIN CERTIFICATE REQUEST-----' in (SELECT data from openca2.request where req_key = 3873)) +0 ,50000) from openca2.request where req_key = 3873
But yours look better as it is shorter :)
So this question is answered. THX again to you both.

Is there pagination for transaction search?

I am trying to execute the TransactionSearchReq method using the PayPal SOAP API and i get the following warning:
ShortMessage: Search warning
LongMessage: The number of results were truncated. Please change your search parameters if you wish to see all your results.
ErrorCode: 11002
SeverityCode: Warning
It also says in the docs that "The maximum number of transactions that can be returned from a TransactionSearch API call is 100."
(https://developer.paypal.com/docs/classic/api/merchant/TransactionSearch_API_Operation_SOAP/)
Is there some way to paginate results so that I can get more than 100 results from multiple queries?
Here's one way you can do it in Rails. This assumes you want to search from a specific point in time until now, but you could change the end_date to specify an end date. Note that I've added the 'paypal-sdk-merchant' gem to my gemfile (see https://github.com/paypal/merchant-sdk-ruby) and followed the instructions to setup my authentication.
The two things you'll want to edit below are the start_date method (to set your own start date) and the do_something(x) method which will be whatever you want to do to each of the individual orders within your date range.
module PaypalTxnSearch
def check_for_updated_orders
begin
#paypal_order_list = get_paypal_orders_in_range(start_date, end_date)
#paypal_order_list.PaymentTransactions.each do |x|
# This is where you can call a method to process each transaction
do_something(x)
end
# TransactionSearch returns up to 100 of the most recent items.
end while txn_search_result_needs_pagination?
end
def get_paypal_orders_in_range(start_date, end_date)
#api = PayPal::SDK::Merchant::API.new
# Build Transaction Search request object
# https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/TransactionSearch_API_Operation_NVP/
#transaction_search = #api.build_transaction_search(
StartDate: start_date,
EndDate: end_date
)
# Make API call & get response
#response = #api.transaction_search(#transaction_search)
# Access Response
return_response_or_errors(#response)
end
def start_date
# In this example we look back 6 months, but you can change it
Date.today.advance(months: -6)
end
def end_date
if defined?(#paypal_order_list)
#paypal_order_list.PaymentTransactions.last.Timestamp
else
DateTime.now
end
end
def txn_search_result_needs_pagination?
##paypal_order_list.Ack == 'SuccessWithWarning' &&
##paypal_order_list.Errors.count == 1 &&
##paypal_order_list.Errors[0].ErrorCode == '11002'
end
def return_response_or_errors(response)
if response.success?
response
else
response.Errors
end
end
end

TSQL PIVOT Function: Invalid column name error and creating calculated column

I'm pretty new to the PIVOT function and I have been trying to figure this out for the past day and a half so I thought I would create an account after lurking for so long and just ask.
I have a table with the layout as follows:
AsOfDt AcctNum MntYr Dt Category Count
4/15/2015 12345 Jan-15 1/18/2015 Registered User 1
4/15/2015 12346 Feb-15 2/7/2015 New Registration User 1
4/15/2015 12347 Jan-15 1/27/2015 Unique Account 1
4/15/2015 12348 Jan-15 1/24/2015 Registered User 1
This is the end result I am trying to achieve
MntYr Account Population New Registration User Registered User Unique Account
Jan 2015 330984 12 26212 26311
Feb 2015 331897 2953 58702 58894
Mar 2015 343561 950 29498 29638
Apr 2015 343181 675 8845 8916
Grand Total 1349623 4590 123257 123759
Here is the Query that I currently have built:
WITH BaseQuery AS (
SELECT
MntYr
,Category
,[Count]
FROM [dbo].[rpt_gen_WebPortal_TestingData]
)
SELECT [MntYr]
,'Account Population'
,'Unique Account'
,'Registered User'
,'New Registration User'
FROM BaseQuery
pivot (sum([count]) for MntYr
in ("Jan 2015", "Feb 2015", "Mar 2015", "Apr 2015" )
) AS Pivoting
My first question:
I am getting an error for my MntYr column in the second SELECT statement, "Invalid column name 'MntYr'." I really don't understand why this is throwing an error. What am I doing wrong with trying to pull that column when I explicitly name it in my BaseQuery pull?
My second question:
I would also like to create a calculated field based upon the percentage of (Unique Account / Account Population), but I'm not quite sure how to go about calculated fields in a PIVOT function. Any ideas on how to get started with this one?
Any and all help would be much appreciated!
Thanks.
Your pivot clause was wrong. You also don't need a CTE. Try this:
SELECT
MntYr
,[Account Population]
,[Unique Account]
,[Registered User]
,[New Registration User]
,case
when isnull([Account Population],0) = 0 then 0
else 100 * [Unique Account] / [Account Population]
end Pct
FROM (
SELECT
MntYr
,Category
,[Count]
FROM [dbo].[rpt_gen_WebPortal_TestingData]
) BaseQuery
pivot (sum([Count]) for Category
in ([Account Population]
,[Unique Account]
,[Registered User]
,[New Registration User] )
) AS Pivoting

Service Broker only receiving one message at a time

Even when I specify Receive Top(25), etc I am only getting one message to be dequeued at a time. Not sure what i am doing wrong inside my sproc? Probably something trivial, but I don't see the problem.
Sproc:
CREATE PROCEDURE dbo.SPP_DEQUEUE_MESSAGE
AS
BEGIN
DECLARE #receiveTable TABLE(
message_type sysname,
message_body xml,
message_dialog uniqueidentifier);
BEGIN TRANSACTION;
WAITFOR
( RECEIVE TOP(25)
message_type_name,
message_body,
conversation_handle
FROM TargetQueue1DB
INTO #receiveTable
), TIMEOUT 3000;
SELECT
*
From #receiveTable;
Delete from #receiveTable;
COMMIT TRANSACTION;
END --End Sproc
Any idea what I am doing wrong?
Thanks,
B
My guess would be that each message belongs to a different conversation (and therefore by default to a different conversation group). If this is the case, then this is expected behavior.
From Books Online - Receive (Transact-SQL):
All messages that are returned by a
RECEIVE statement belong the same
conversation group
If you want to receive multiple messages at once, send multiple messages on a single conversation or group multiple conversations into a single conversation group on the receiving end.
Do you know how many messages are in that queue, before the proc is run?
If you run the following query to get the count in all your queues
SELECT sq.name,
p.rows
FROM sys.service_queues sq
Join sys.internal_tables it ON sq.object_id = it.parent_id
AND it.parent_minor_id = 0
AND it.internal_type = 201
Join sys.indexes as i on i.object_id = it.object_id and i.index_id = 1
Join sys.partitions as p on p.object_id = i.object_id and p.index_id = i.index_id
WHERE
sq.object_id = it.parent_id AND
it.parent_minor_id = 0 AND
it.internal_type = 201
If there is more than 1 message in that queue, you should get more than 1 in your receive.