ASTERISK. Adding a header to the CDR - asterisk

Aterisk 13. Customized diplane. Calls are working, CDR is written.
But I need to add my own title to the CDR during the call.
Example extensions.conf:
exten => _1XX, n, SIPAddHeader (Test-header: 123) exten => _4XX, n, Set (CDR (Test column) = $ {SIP_HEADER (Test-header)})
Console output:
Executing [6001 # test: 2] SIPAddHeader ("SIP / 100-00000000", "Test-header: 123") in new stack - Executing [6001 # test: 2] Set ("SIP / 100-00000000" CDR (Test-header) = ") in new stack
Why is the value of the header not transmitted? And is it possible to do this at all? P.S. The column Test-header in the database is

The userfield solution should work, but if you need more than one column, the CDR MySQL backend supports custom columns. In cdr_mysql.conf, create this section:
[columns]
alias testcolumn => testcolumn
And in your dialplan:
Set(CDR(testcolumn)=${SIP_HEADER(Test-header)})
Asterisk will not create this column in the CDR table, you have to ALTER it:
ALTER TABLE cdr ADD COLUMN testcolumn VARCHAR(255) DEFAULT NULL;

You have CDR(userfield) value
Custom cdr field work only on some drivers(seams like only in res_mysql) and only if column present in db at asterisk start.

Related

How to delete orddict in Erlang

I want to be able to delete multiple keys in Erlang and also have a way to erase all dictionary.
I have tried so far:
X=[{1,2},{3,4}].
Deleted=orddict:fold(fun({K,V})->orddict:erase(K,X) end ,[],X).
How do i erase all the keys?Do i need to use an external variable in my case X in the fun -> erase method ?
As you try in your code, you cannot erase a key in an orddict, but you can create a copy of it without the key.
If you want to remove all the keys, just do what #choroba says, create a new orddict.
If you want to remove multiple but not all keys, there are many ways to achieve what you want, I propose you a solution using the function take, from orddict library:
take(Key, Orddict) -> {Value, Orddict1}
| error
Orddict = Orddict1 = orddict(Key, Value)
Key = Value = term()
This function returns value from dictionary and new dictionary without
this value. Returns error if the key is not present in the dictionary.
First you create a function that take as argument a key an a Dict and return a dict without the key (if it exists)
1> F = fun(X,Dict) -> case orddict:take(X,Dict) of
1> {_,New} -> New;
1> error -> Dict
1> end
1> end.
#Fun<erl_eval.13.91303403>
edit: I didn't check the orddict library, you can use the erase function replacing F with G = fun(X,Dict) -> orddict:erase(X,Dict) end.
Then you can use this function with lists:fold/3 to "remove" in your dict all keys from a list:
2> O1 =orddict:from_list([{1,a},{2,b},{3,c},{4,d}]).
[{1,a},{2,b},{3,c},{4,d}]
3> O2 = lists:foldl(F,O1,[3,1]).
[{2,b},{4,d}]
4> O3 = lists:foldl(F,O1,[3,5]).
[{1,a},{2,b},{4,d}]
5>

Clojure map outside scope

I am trying to save data into a collection of some sort, but the program that I have is saving everything into a separate map. I want to make it one map.
(defn readFile []
(map (fn [line] (clojure.string/split line #";"))
(with-open [rdr (reader "C:/Users/Rohil/Desktop/textfile.txt")]
(doseq [[idx line] (map-indexed vector(line-seq rdr))]
(if(.contains line "201609")
(if(not(.contains line "TBA"))
(println(assoc table :code(nth(clojure.string/split line #";")3) :instructor(nth(clojure.string/split line #";")19)))
)
)
)
)
)
)
)
Any help will be appreciated.
Looks like you are adapting to clojure :-) I went to the same process. Hang on, it will be worth it!
First: it is important to realize that map will save the result of the function into a new collection. Like cfrick mentions, println returns nil and assoc does not change a map.
I'm guessing a bit here what you are trying to do: You want to have a collection of dicts, where every dict has two keys, like so:
[
{ :code 1 :instructor "blah"}
{ :code 2 :instructor "boo" }
]
You need these values to come from a file, but you only want to save the lines where the line contains "201609" but not "TBA"
First some general remarks:
You probably want to split this function into smaller parts. One could be the check for lines (contains 201609 but not tba ), another could read the file...
I know it is the title of your question, but most likely there is a better way than to change a global variable. Maybe you could make the function readFile return the table?
try if you can pass in arguments to your function.
I'm not sure what you are trying to do with the line (doseq [[... Please give us more context there. I will ignore it
Here is a possible solution:
(ns test
(:require [clojure.string :as s]
[clojure.java.io :as io]))
(defn line-filter [include exclude line]
(and (not (s/includes? line exclude))
(s/includes? line include)))
(defn process-line [line]
(let [line-parts (s/split line #";")
code (nth line-parts 3)
instructor (nth line-parts 19)]
{:code code :instructor instructor}))
(defn read-file [file-name]
(s/split (slurp (io/resource file-name)) #"\n"))
(defn parse-lines [lines]
(map process-line lines))
(defn read-file-and-parse
"This function will read a file, process the lines, and output a collection of maps"
[filename search-for exclude]
(parse-lines
(filter #(line-filter search-for exclude %)
(read-file filename))))
you could now call this function like this: (read-file-and-parse "test.txt" "201609" "TBA")
If you want to add the result of this function into your table, you can use concat. But again, this will return a new version of your list (with new entries added) and not change the one you defined earlier.
Welcome to functional programming :-)))

MERGE after checking the condition in neo4j

In this If i deleted "aravind" the node "ramya" has to be connected to "sreepad". For that I written a query
MATCH (m)<-[:createdBy]-(n:Login{UserName:"aravind"})<-[:createdBy]-(z)
merge (m)<-[:createdBy]-(z)
set z.createdBy=m.UserName
detach delete n
Its working fine when the node has a tail. But not working on the end user (Suppose "prem"). How to write a query which works for both ???
Thanks in advance
You need:
1) Get node for delete
2) Get parent node
3) Collect child nodes
4) Create relationships
5) Delete node
MATCH (n:Login{UserName:"aravind"})
OPTIONAL MATCH (n)->[:createdBy]-(m)
OPTIONAL MATCH (n)<-[:createdBy]-(z)
WITH n, collect(m)[0] as m, collect(z) as zs
FOREACH(z in zs |
merge (m)<-[:createdBy]-(z)
set z.createdBy=m.UserName
)
detach delete n

Parsing a delimited string

I need to implement a linked list in ADA that has a node of 3 parts that include:
1. name of the node
2. value of the node
3. name of the next node
I need to take inputs from user, with each part of the node ending with a ";"
e.g
This is what input on command line must look like
a;22;b
b;33;c
c;43
The LL ends at c. So we have nothing after the value
I can implement a LL, but how am I supposed to read the ';' in the input and assign it to the respective node dynamically to build the linked list???
Assuming you have a string Input which contains one of your nodes' data (for example, ”a;22;b”), you can find the position of the first semicolon using
First_Semicolon : Natural :=
Ada.Strings.Fixed.Index (Source => Input,
Pattern => ";”,
From => Input'First);
and the last semicolon using
Last_Semicolon : Natural :=
Ada.Strings.Fixed.Index (Source => Input,
Pattern => ";",
From => Input'Last,
Going => Ada.Strings.Backward);
The node Name is then the substring of input from the beginning to one before the first semicolon,
Input (Input'First .. First_Semicolon - 1)
If First_Semicolon and Last_Semicolon are equal, then you have the case where there’s no next node name, and the node Value is
Natural'Value (Input (First_Semicolon + 1 .. Input'Last))
but if they aren’t equal the next node name is present, so the node Value comes from the part of Input between the semicolons,
Natural'Value (Input (First_Semicolon + 1 .. Last_Semicolon - 1))
and the Next_Node_Name from the remainder of Input,
Input (Last_Semicolon + 1 .. Input’Last)
Obviously there’s no error checking here, and there’s a lot that could go wrong. I’ve not discussed creating the linked list, either, because you say you can do that (personally I’d use Ada.Containers.Doubly_Linked_Lists ...)

Pulling out a column in all records in a Sqlite table into a concatenated string in Haskell with Persist

I'm trying to learn Haskell, specifically Snap, Blaze HTML5 and Persist. I would like to take every row in a table, select a single column from it, and then concatenate the values into a single string.
I've previously worked with C#'s LINQ quite extensively and under Entity Framework I could do it like this:
String.Join(", ", dbContext.People.Select(p => p.Name));
This would compile down to SELECT Name FROM People, with C# then concatenating those rows into a string with ", " in between.
To try and get the concatenation part right, I put this together, which seems to work:
intercalate ", " $ map show [1..10]
(it counts 1-9, concatenates with ", " in between the items)
However, I can't get this to work with Database.Persist.Sqlite. I'm not sure I quite understand the syntax here in Haskell. To contact the DB and retrieve the rows, I have to call: (as far as I understand)
runSqlite "TestDB" $ selectList ([] :: [Filter Person]) [] 0 0
The problem is that I'm not sure how to get the list out of runSqlite. runSqlite doesn't return the type I'm after, so I can't use the return value of runSqlite. How would I do this?
Thank you for reading.
To clarify:
Snap requires that I define a function to return the HTML I wish to send back to the client making the HTTP request. This means that:
page = runSqlite "TestDB" $ do
{pull data from the DB)
Is no-go as I can't return the data via the runSqlite call, and as far as I know I can't have a variable in the page function which is set within the runSqlite do block. All examples I can find just write to IO in the runSqlite do block, which is not what needs to be done here.
The type of runSqlite is:
runSqlite :: (MonadBaseControl IO m, MonadIO m) => Text -> SqlPersistT (NoLoggingT (ResourceT m)) a -> m a
And the type of selectList is:
[Filter val] -> [SelectOpt val] -> m [Entity val]
So, you can actually, use the nice do notation of Monad, to extract it:
runSqlite "TestDB" $ do
myData <- selectList ([] :: [Filter Person]) [] 0 0
-- Now do stuff with myData
The <- thing gets the list out of the monad. I would suggest you to go through this chapter to get an idea of how Persistent is used. Note that the chapters in the book assume a basic Haskell understanding.
The issue is that I want to use the selectList outside of runSqlite as
I need to pass the concatenated string to a Blaze HTML5 tag builder:
body $ do p (concatenated list...)
For this case, just define a function that does your intended task:
myLogic :: [SqlColumnData] -> String -- Note that SqlColumnData is hypothetical
myLogic xs = undefined
And then just call them appropriately in your main function:
main = runSqlite "TestDB" $ do
myData <- selectList ([] :: [Filter Person]) [] 0 0
let string = myLogic myData
-- do any other remaining stuff
It hadn't clicked that if I didn't use a do block with runSqlite, the result of the last call in the statement was the return value of the statement - this makes total sense.
https://gist.github.com/egonSchiele/5400694
In this example (not mine) the readPosts function does exactly what I'm after and cleared up some Haskell syntax confusion.
Thank you for your help #Sibi.

Resources