I am aggregating the contents of an InputStream using a BufferedReader using the form
while( (str = br.readLine()) != null){
sb.append(str)
}
but this quickly caused an OutOfMemoryError as the null check failed to pick up the null and my StringBuffer keeps increasing in size...
I have verified that str does have a value of null and also verified that it is not "null".
Refactoring my code to
str = br.readLine()
while(str != null){
sb.append(str)
str = br.readLine()
}
works but I've no idea how this would be any different. Any ideas?
In scala the expression str = br.readline() yield return value of type Unit, which is always not equal to null. It should have given you a warning about comparing Unit to null.
You are correct to refactor it like that.
P.S. As #Jesper correctly commented your question, this is not the way you usually read a file in scala. So if you do that - please use his code example. If you have any other InputStream, you can use Source.fromInputStream
Archeg has explained it beautifully so try this :
var str = ""
while({str = br.readLine; str != null}) {
}
and since you are working in Scala, try using
scala.io.Source.fromInputStream(is).getLines().mkString("\n")
or
val bufferedReader = new BufferedReader(inputStreamReader)
Iterator continually bufferedReader.readLine takeWhile (_ != null) mkString
Related
I'm pretty new to Dart and I got some problems with understanding what is going on under the hood. I've simple code like this:
void main() {
String s1 = "test1";
StringBuffer sb = StringBuffer();
sb.write("test");
sb.write("1");
String s2 = sb.toString();
print(identical(s1, s2));
print(s1 == s2);
int a = 1;
int b = 1;
print(identical(a, b));
}
result of this code is 3x true
Which is little tricky for me. As I understands all variables refers to some values, and since == operator is expected to return true, I'm little confused why identical also return true. If I would use code like:
String s1 = "test1";
String s2 = "test1";
Then I would expect that there is compiler optimization for immutable strings. But since I combine it via StringBuffer I would expect that I got two different values in memory. I suspect that identical uses == operator internally... Why I'm curious: I'm working on app which will use sets of tags. And I'm not sure If should I create some pool of strings and checks if some strings are already created and reuse it or just spawn strings and Dart has it's own string pool?
I've created a custom Magic command with the intention of generating a spark query programatically. Here's the relevant part of my class that implements the MagicCommandFunctionality:
MagicCommandOutcomeItem execute(MagicCommandExecutionParam magicCommandExecutionParam) {
// get the string that was entered:
String input = magicCommandExecutionParam.command.substring(MAGIC.length())
// use the input to generate a query
String generatedQuery = Interpreter.interpret(input)
MIMEContainer result = Text(generatedQuery);
return new MagicCommandOutput(MagicCommandOutcomeItem.Status.OK, result.getData().toString());
}
This works splendidly. It returns the command that I generated. (As text)
My question is -- how do I coerce the notebook into evaluating that value in the cell? My guess is that a SimpleEvaluationObject and TryResult are involved, but I can't find any examples of their use
Rather than creating the MagicCommandOutput I probably want the Kernel to create one for me. I see that the KernelMagicCommand has an execute method that would do that. Anyone have any ideas?
Okay, I found one way to do it. Here's my solution:
You can ask the current kernelManager for the kernel you're interested in,
then call PythonEntryPoint.evaluate. It seems to do the job!
#Override
MagicCommandOutcomeItem execute(MagicCommandExecutionParam magicCommandExecutionParam) {
String input = magicCommandExecutionParam.command.substring(MAGIC.length() + 1)
// this is the Scala code I want to evaluate:
String codeToExecute = <your code here>
KernelFunctionality kernel = KernelManager.get()
PythonEntryPoint pep = kernel.getPythonEntryPoint(SCALA_KERNEL)
pep.evaluate(codeToExecute)
pep.getShellMsg()
List<Message> messages = new ArrayList<>()
//until there are messages on iopub channel available collect them into response
while (true) {
String iopubMsg = pep.getIopubMsg()
if (iopubMsg == "null") break
try {
Message msg = parseMessage(iopubMsg) //(I didn't show this part)
messages.add(msg)
String commId = (String) msg.getContent().get("comm_id")
if (commId != null) {
kernel.addCommIdManagerMapping(commId, SCALA_KERNEL)
}
} catch (IOException e) {
log.error("There was an error: ${e.getMessage()}")
return new MagicKernelResponse(MagicCommandOutcomeItem.Status.ERROR, messages)
}
}
return new MagicKernelResponse(MagicCommandOutcomeItem.Status.OK, messages)
}
My Google-fu is letting me down, so I'm hoping you can help
I'm building some webservices is the play framework using scala and anorm for database access
One of my calls is to update an existing row in a database - i.e run a query like
UPDATE [Clerks]
SET [firstName] = {firstName}
,[lastName] = {lastName}
,[login] = {login}
,[password] = {password}
WHERE [id] = {id}
My method receives a clerk object BUT all the parameters are optional (except the id of course) as they may only wish to update a single column of the row like so
UPDATE [Clerks]
SET [firstName] = {firstName}
WHERE [id] = {id}
So I want the method to check which clerk params are defined and build the 'SET' part of the update statement accordingly
It seems like there should be a better way than to go through each param of the clerk object, check if it is defined and build the query string - but I've been unable to find anything on the topic so far.
Does anyone have any suggestions how this is best handled
As the commenters mentioned it appears to not be possible - you must build the query string yourself.
I found that examples around this lacking and it took more time to resolve this than it should have (I'm new to scala and the play framework, so this has been a common theme)
in the end this is what I implemented:
override def updateClerk(clerk: Clerk) = {
var setString: String = "[modified] = {modified}"
var params: collection.mutable.Seq[NamedParameter] =
collection.mutable.Seq(
NamedParameter("modified", toParameterValue(System.currentTimeMillis / 1000)),
NamedParameter("id", toParameterValue(clerk.id.get)))
if (clerk.firstName.isDefined) {
setString += ", [firstName] = {firstName}"
params = params :+ NamedParameter("firstName", toParameterValue(clerk.firstName.getOrElse("")))
}
if (clerk.lastName.isDefined) {
setString += ", [lastName] = {lastName}"
params = params :+ NamedParameter("lastName", toParameterValue(clerk.lastName.getOrElse("")))
}
if (clerk.login.isDefined) {
setString += ", [login] = {login}"
params = params :+ NamedParameter("login", toParameterValue(clerk.login.getOrElse("")))
}
if (clerk.password.isDefined) {
setString += ", [password] = {password}"
params = params :+ NamedParameter("password", toParameterValue(clerk.password.getOrElse("")))
}
if (clerk.supervisor.isDefined) {
setString += ", [isSupervisor] = {supervisor}"
params = params :+ NamedParameter("supervisor", toParameterValue(clerk.supervisor.getOrElse(false)))
}
val result = DB.withConnection { implicit c =>
SQL("UPDATE [Clerks] SET " + setString + " WHERE [id] = {id}").on(params:_*).executeUpdate()
}
}
it likely isn't the best way to do this, however I found it quite readable and the parameters are properly handled in the prepared statement.
Hopefully this can benefit someone running into a similar issue
If anyone wants to offer up improvements, they'd be gratefully received
Since roughly 2.6.0 this is possible directly with anorm using their macros, http://playframework.github.io/anorm/#generated-parameter-conversions
Here is my example:
case class UpdateLeagueFormInput(transferLimit: Option[Int], transferWildcard: Option[Boolean], transferOpen: Option[Boolean])
val input = UpdateLeagueFormInput(None, None, Some(true))
val toParams: ToParameterList[UpdateLeagueFormInput] = Macro.toParameters[UpdateLeagueFormInput]
val params = toParams(input)
val dynamicUpdates = params.map(p => {
val snakeName = camelToSnake(p.name)
s"$snakeName = CASE WHEN {${p.name}} IS NULL THEN l.$snakeName ELSE {${p.name}} END"
})
val generatedStmt = s"""UPDATE league l set ${dynamicUpdates.mkString(", ")} where league_id = ${league.leagueId}"""
SQL(generatedStmt).on(params: _*).executeUpdate()
producing:
UPDATE league l set transfer_limit = CASE WHEN null IS NULL THEN l.transfer_limit ELSE null END, transfer_wildcard = CASE WHEN null IS NULL THEN l.transfer_wildcard ELSE null END, transfer_open = CASE WHEN true IS NULL THEN l.transfer_open ELSE true END where league_id = 26;
Notes:
The camelToSnake function is just my own (There is an obvious ColumnNaming.SnakeCase available for parser rows, but I couldn't find something similar for parameter parsing)
My example string interpolates {league.leagueId}, when it could treat this as a parameter as well
Would be nice to avoid the redundant sets for null fields, however I don't think it's possible, and in my opinion clean code/messy auto-generated sql > messy code/clean auto-generated sql
So I have had an issue for a while now and thought it was worth the time to ask the more experienced regex guys if there was a way to fix this issue with a quick search and replace.
So i use a tool which generates java code(not written in java or I would manually fix the cause directly), however, it has an issue calling variables before an object is created.
This always occurs only once per object, but not for every object, the object name is unknown, and the error is always the line directly before the constructor is called. This is the format the error is always in:
this.unknownObjectName.mirror = true;
this.unknownObjectName = new Model(unknown, parameter, values);
I know there should be a trick to fix this, as a simple string replace simply will not work since 'unknownObjectName' is unknown.
Would this even be possible with regex, if so, please enlighten me :)
This is how the code SHOULD read:
this.unknownObjectName = new Model(unknown, parameter, values);
this.unknownObjectName.mirror = true;
For complex models, this error may happen hundreds of times, so this will indeed save a lot of time. That and I would rather walk on hot coals then do mindless busy work like fixing all these manually :)
Edit:
I through together a java app that does the job.
public static void main(String args[]){
File file = new File(args[0]);
File file2 = new File(file.getParentFile(), "fixed-" + file.getName());
try {
if(file2.exists()) {
file2 = new File(file.getParentFile(), "fixed-" + System.currentTimeMillis() + "-" + file.getName());
}
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2)));
String line, savedline = null, lastInitVar = "";
while((line = br.readLine()) != null){
if(line.contains("= new ")){
String varname = line.substring(0, line.indexOf("=")).trim();
lastInitVar = varname;
}else if(line.contains(".mirror")){
String varname = line.substring(0, line.indexOf(".mirror")).trim();
if(!lastInitVar.equals(varname)){
savedline = line;
continue;
}
}else if(savedline != null && savedline.contains(lastInitVar)){
bw.write(savedline + "\n");
savedline = null;
}
bw.write(line + "\n");
}
bw.flush();
bw.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Over thinking it
Write a program to read line by line and when you see a object access before a constructor don't write it out, write out the next line and then write out the buffered line, rinse repeat.
Some people, when confronted with a problem, think "I know, I'll use
regular expressions." Now they have two problems. - Jamie Zawinski
Regular Expressions are for matching patterns not state based logic.
a quick question really.
I'm struggling to implement Linq2Entities statement that could take more than one value for a particular "field". I'm passing a number of strings to the getClientsProjected() I can easily compare single value. But I've got on my page multiple dropdown and out of that I get string separated with coma I then later use to split it to string[] e.g. __ACCOUNT_SITE = "1234,5678" (see the code below) I've tried for/foreach/contains none of which worked...
public IQueryable<ClientViewModel> getClientsProjected(string __ACCOUNT_SITE, string __ACCOUNT)
{
var projectedClients = from c in getClosedSRs()
select new ClientViewModel
{
_ACCOUNT_ID_CSR = c.ACCOUNT_ID_CSR,
_ACCOUNT = c.ACCOUNT,
_ACCOUNT_FAMILY = c.ACCOUNT_FAMILY,
...
...
_ACCOUNT_SITE = c.ACCOUNT_SITE
};
if (String.IsNullOrEmpty(__ACCOUNT) != true && __ACCOUNT != "ALL")
{
//this works fine as an __ACCOUNT is of a single value
projectedClients = projectedClients.Where(c => c._ACCOUNT == __ACCOUNT);
}
if (String.IsNullOrEmpty(__ACCOUNT_SITE) != true && __ACCOUNT_SITE != "ALL")
{
String[] splitSites = __ACCOUNT_SITE.Split(',');
//????????????????????????????????????????????????
}
return projectedClients;
}
Now, to most of you this will make complete sense. I've read many articles but did not find a proper answer. I however can't use Linq2SQL as already built my entire site using L2E, interface and ReportViewer.
Any workaround?
If you are trying to filter projectedClients based on the values in splitSites, then use:
if (String.IsNullOrEmpty(__ACCOUNT_SITE) != true && __ACCOUNT_SITE != "ALL")
{
String[] splitSites = __ACCOUNT_SITE.Split(',');
projectedClients = projectedClients.Where(x => splitSites.Contains(x._ACCOUNT);
}