These are chat archives for synrc/n2o

Jan 2016
Ram Kumar
Jan 04 2016 05:24

Hi, is there any method / example to validate the data that is being stored into the db to check for duplication e.g. duplicate e-mail address or duplicate username ? I've tested using the

#user{id=Email, username=Username, email=Email, firstName=FirstName, lastName=LastName, password=PasswordDigest,  date_of_birth=DOB, register_date=Current_Date }.

I ran a test whereby I used different email addresses and stored correctly, row after row, but when I used the same email twice, it overwrites. I am trying to create an alert message to notify the user that the e-mail i.e. account already exists, if the email doesn't exist and the username is taken then different alert message.

if Email =:= users:get_email(email) ->
  wf:info("User Already Exists");
  if Username =:= users:get_username(username) ->
    wf:info("Username Already Taken");
   true -> users:populate(USER)

can this be placed in an event method?

Namdak Tonpa
Jan 04 2016 06:39
not sure what you mean
6> kvs:add(#user{id=""}).
{ok,#user{id = "",version = undefined,
          container = feed,feed_id = user,prev = undefined,
          next = undefined,feeds = [],guard = true,etc = undefined,
          email = undefined,username = undefined,password = undefined,
          display_name = undefined,register_date = undefined,
          tokens = [],images = undefined,names = undefined,
          surnames = undefined,birth = undefined,sex = undefined,
          date = undefined,status = undefined,zone = undefined,
          type = undefined}}
7> kvs:add(#user{id=""}).
uniqueness is controlled by keys
Ram Kumar
Jan 04 2016 11:29

@5HT I'm unable to get the error. This is the response I'm receiving:-

This first is correct:

=INFO REPORT==== 4-Jan-2016::19:19:49 ===
wf_convert:BERT {io,_,_}: {io,<<"{ var x=qi('button_login'); x && x.addEventListener('click',function (event){ { if (validateSources(['login_email','login_password'])) {  ws.send(enc(tuple(atom('pickle'),bin('button_login'),bin('g2gCaAVkAAJldmQABWluZGV4ZAAFbG9naW5rAAxidXR0b25fbG9naW5kAAVldmVudGgDYgAABatiAA3UlWIABMUt'),[tuple(tuple(utf8_toByteArray('button_login'),bin('detail')),[]),tuple(atom('login_email'),querySource('login_email')),tuple(atom('login_password'),querySource('login_password'))]))); } else console.log('Validation Error'); }});};{ var x=qi('signupButton'); x && x.addEventListener('click',function (event){ { if (validateSources(['fName','lName','userName','eMail','pWord','dobDatePicker'])) {  ws.send(enc(tuple(atom('pickle'),bin('signupButton'),bin('g2gCaAVkAAJldmQABWluZGV4ZAAGc2lnbnVwawAMc2lnbnVwQnV0dG9uZAAFZXZlbnRoA2IAAAWrYgAN1JViAATFkA=='),[tuple(tuple(utf8_toByteArray('signupButton'),bin('detail')),[]),tuple(atom('fName'),querySource('fName')),tuple(atom('lName'),querySource('lName')),tuple(atom('userName'),querySource('userName')),tuple(atom('eMail'),querySource('eMail')),tuple(atom('pWord'),querySource('pWord')),tuple(atom('dobDatePicker'),querySource('dobDatePicker'))]))); } else console.log('Validation Error'); }});};">>,

=INFO REPORT==== 4-Jan-2016::19:19:54 ===
n2o_nitrogen:Pickle: {pickle,<<"signupButton">>,


The following I am testing using the same email which is the ID but it is still able to write over the table

=INFO REPORT==== 4-Jan-2016::19:22:32 ===
wf_convert:BERT {io,_,_}: {io,<<"{ var x=qi('button_login'); x && x.addEventListener('click',function (event){ { if (validateSources(['login_email','login_password'])) {  ws.send(enc(tuple(atom('pickle'),bin('button_login'),bin('g2gCaAVkAAJldmQABWluZGV4ZAAFbG9naW5rAAxidXR0b25fbG9naW5kAAVldmVudGgDYgAABatiAA3VOGIACBSV'),[tuple(tuple(utf8_toByteArray('button_login'),bin('detail')),[]),tuple(atom('login_email'),querySource('login_email')),tuple(atom('login_password'),querySource('login_password'))]))); } else console.log('Validation Error'); }});};{ var x=qi('signupButton'); x && x.addEventListener('click',function (event){ { if (validateSources(['fName','lName','userName','eMail','pWord','dobDatePicker'])) {  ws.send(enc(tuple(atom('pickle'),bin('signupButton'),bin('g2gCaAVkAAJldmQABWluZGV4ZAAGc2lnbnVwawAMc2lnbnVwQnV0dG9uZAAFZXZlbnRoA2IAAAWrYgAN1ThiAAgU2w=='),[tuple(tuple(utf8_toByteArray('signupButton'),bin('detail')),[]),tuple(atom('fName'),querySource('fName')),tuple(atom('lName'),querySource('lName')),tuple(atom('userName'),querySource('userName')),tuple(atom('eMail'),querySource('eMail')),tuple(atom('pWord'),querySource('pWord')),tuple(atom('dobDatePicker'),querySource('dobDatePicker'))]))); } else console.log('Validation Error'); }});};">>,
=INFO REPORT==== 4-Jan-2016::19:22:52 ===
n2o_nitrogen:Pickle: {pickle,<<"signupButton">>,
Namdak Tonpa
Jan 04 2016 11:30
kvs:put overwrites, kvs:add checks
I don't see the code how you perform addition
Ram Kumar
Jan 04 2016 11:32
for this I'm using the n2o review example which is using the ets
-compile({parse_transform, rest}).
-export([init/0, populate/1, exists/1, get/0, get/1, post/1, delete/1]).

init()               -> ets:new(users, [public, named_table, {keypos,}]).
populate(Users)      -> ets:insert(users, Users).
exists(Id)           -> ets:member(users, wf:to_list(Id)).
get()                -> ets:tab2list(users).
get(Id)              -> #user{id=Id}.
delete(Id)           -> ets:delete(users, wf:to_list(Id)).
post(#user{} = User) -> ets:insert(users, User);
post(Data)           -> post(from_json(Data, #user{})).
I'm using the post and populate here
Namdak Tonpa
Jan 04 2016 11:33
this is not the database
this is ets
inmemory table
this is REST sample, it is sample for synrc/rest not for n2o
synrc/rest is REST framework, synrc/n2o is WebSocket application Server
synrc/kvs is a database wrapper
you don't need REST for building n2o applications
provided example is like REST interface for inmemory table in ETS
ETS is like memcache in Erlang world
what you need to develop your first N2O application is to develop your protocol
put it in page module event(Protocol)
with all clauses
Namdak Tonpa
Jan 04 2016 11:38
and write handlers for each protocols message right in the body of event/1 API
for storing data you may or may not use a kvs
Ram Kumar
Jan 04 2016 11:39
I've given the mnesia config, can this be pointed to the kvs
Namdak Tonpa
Jan 04 2016 11:40
I haven't seen any line of code that writes to kvs
in n2o/sample review application there is a sample how to deal with kvs
users.erl is an example for different library
for synrc/rest
that is how we inspecting protocol from n2o sources:
$ cat index.erl | grep "event("
event(init) ->
event(logout) ->
event(chat) ->
event(#client{data={User,Message}}) ->
event(#bin{data=Data}) ->
event(#ftp{sid=Sid,filename=Filename,status={event,stop}}=Data) ->
event(Event) ->
Namdak Tonpa
Jan 04 2016 11:45
routing selecting the module containing event/1 function
it's simple
no REST needed
Ram Kumar
Jan 04 2016 11:46
that's fine
Namdak Tonpa
Jan 04 2016 11:46
e.g. if we need to save chat message in database
we just perform:
so we use WebSocket as a channel, our protocol is visible in code, and we write handlers for protocol messages that interact with pages. That's it.
Ram Kumar
Jan 04 2016 11:49
that is a good way for realtime
Namdak Tonpa
Jan 04 2016 11:50
we wrote synrc/rest as example for connectivity with REST clients, it is not a recommended way of building n2o applications
Ram Kumar
Jan 04 2016 11:51
Namdak Tonpa
Jan 04 2016 11:51
and synrc/rest still lacks of full kvs support
it should be one kvs handler that can write to any table given by url
consider having universal REST endpoint for any table (not only user) automatically
what you've used is just handcoded REST handler for user ETS-based tables, not even kvs
Ram Kumar
Jan 04 2016 11:53
yes.. didn't go far with that
Ram Kumar
Jan 04 2016 11:58
I think its doing something now
Ram Kumar
Jan 04 2016 12:16
@5HT quick question what do I need to do for this:
2> kvs:add(#user{id=""}).
  • 3: record user undefined
Ilya Gorskin
Jan 04 2016 13:54
@ramka001 rr("user.hrl")
Ram Kumar
Jan 04 2016 17:37

Hi @Revent , adding the rr("user.hrl") for debug doesn't produce any error messages. I've done a few things:-
Added a users.erl file to include

metainfo() ->

updated the sys.config and added the users to this:-

 {kvs, [{dba,store_mnesia},
        {schema, [kvs_user, kvs_acl, kvs_feed, kvs_subscription, users ]} ]}
trigger_kvs() ->

the table is users table is created but data doesn't get inserted followed with the kvs:add(....)

Namdak Tonpa
Jan 04 2016 18:30
you have in schema doubling #user table (kvs_user and users)
this is wrong
take a look carefully on examples
in case you don't understand what you are doing
also you shouldn't start applications manually and dealing with schema