<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<META NAME="Generator" CONTENT="MS Exchange Server version rmj.rmm.rup.rpr">
<TITLE>RE: [erlang-questions] I need some advices for a framework I'm doing</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Hi, </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Well the good news here is that I am making it together with a system a am also doing so, it any problems present I will notice they quickly and at the same time</FONT></SPAN><SPAN LANG="en-us"> <FONT FACE="Calibri">I will get feedbacks.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Regards documentation, that one of the thing a l</FONT></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri">o</FONT></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri">ve more, so it will be plenty of it, with a lot of examples and explanations.</FONT></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri"> Currently the code doc for any function and even examples of how to use them.</FONT></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri"></FONT></SPAN><SPAN LANG="en-us"> <FONT FACE="Calibri">i</FONT></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri">.e.</FONT></SPAN><SPAN LANG="en-us"> <FONT FACE="Calibri">this is a nice doc for one of the functions:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">%% -------------------------------------------------------------------</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% @doc</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% Makes a query to a database using a 'DBSession'.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% Returns a 'ResultData':</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% - 'ResultData' depends of 'result_format' Option.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% - 'result_format' could be one of 'raw', 'proplist', 'map'.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% - 'proplist' and 'map' result formats have the same</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'ResultData' struct:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% {ok, Data} when using 'select'.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% {ok, Count} when using 'update', 'insert', 'delete'.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% {ok, Count, Data} when using 'update', 'insert' with returning.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% The only differences are:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 0 result</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">s</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'map' -> no_data,</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'proplist' -> [],</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 1 result:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'map' -> a single map #{...},</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'proplist' -> a list of proplist [[...]], (templ</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">ate</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas"></FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"> <FONT FACE="Consolas">c</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">omp</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">atible</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">)</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% N result</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">s</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'map' -> a list of maps [#{...}, ...],</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'proplist' -> a list of proplists [[...], ...],</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% 'raw' by the other hand is 'Backend' dependent.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% Example:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% {ok, #{id := Id}} = database_manager:query(DBSession,</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% Query, Params, [{result_format, map}]).</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% NOTE: 'map' is the default result format for 'query/3' function.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% NOTE: All result format has its pros and cons, 'raw' is the fastest</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% but uncomfortable to deal with, 'map' is the slowest but very</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% easy to deal with. So this is the performance order from</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% fastest to slowest 'raw' > 'proplist' > 'map'.</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"> <FONT FACE="Consolas">'</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">p</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">roplist</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas">'</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Consolas"> can</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% be used to return directly to a template.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% @end</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">%% -------------------------------------------------------------------</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">-spec query(DBSession, Query, Params, Options) -></FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> ResultData | {error, Reason} when</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> DBSession :: db_session(),</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> Query :: string() | bitstring(),</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> Params :: [] | [any(), ...],</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> Options :: proplists:proplist(),</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> ResultData :: any(),</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> Reason :: term().</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas">query({Backend, Connection}, Query, Params, Options) -></FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> %% executes query/4 in the current 'Backend'.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Consolas"> Backend:query(Connection, Query, Params, Options).</FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Anyone have more</FONT></SPAN><SPAN LANG="en-us"> <FONT FACE="Calibri">suggestions</FONT></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri"> I could use?, thanks in advantage.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Regards,</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Ivan.</FONT></SPAN><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">-----Original Message-----<BR>
From: Loïc Hoguin [<A HREF="mailto:essen@ninenines.eu">mailto:essen@ninenines.eu</A>]<BR>
Sent: Monday, August 24, 2015 5:45 PM<BR>
To: Ivan Carmenates Garcia; erlang-questions@erlang.org<BR>
Subject: Re: [erlang-questions] I need some advices for a framework I'm doing</FONT></SPAN><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">On 08/24/2015 10:20 PM, Ivan Carmenates Garcia wrote:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">> Hi everyone, I am making a little framework for cowboy, but in general </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">> what I need is some advices regards final looking, i.e.:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">OK I am a bit lost on everything you explained so allow me to give some generic advice:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Make it work</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Start making apps with it</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Notice everything inefficient in how you now write apps</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Update your framework</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Repeat</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Practice makes perfect. Add a little of looking at how everyone else does things in the mix to get ideas; sometimes you will notice something is bad in your framework but have no idea how to make it better, that's why you need to look elsewhere. Sometimes the idea might come from a completely unrelated source.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">A few more things:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Keep it simple and explicit</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Focus on the use cases that benefit the majority of users</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Choose good, short names</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">* Write a user guide when things stabilize</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">On the last point, you want the guide separate from code entirely because this forces you to think about how you really use it rather than just documenting functions or modules one after another. Think of it like writing a book, except the only role of this book is to explain to others *what* they can do with your framework and *why* they will do things that way.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Once you get there, you should have a pretty good product, and you'll most likely have gotten a ton of users along the way.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Cheers,</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">--</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Loïc Hoguin</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN><A HREF="http://ninenines.eu"><SPAN LANG="en-us"><FONT FACE="Calibri">http://ninenines.eu</FONT></SPAN><SPAN LANG="en-us"></SPAN></A><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">Author of The Erlanger Playbook,</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Calibri">A book about software development using Erlang</FONT></SPAN><SPAN LANG="en-us"></SPAN></P>
</BODY>
</HTML>