2015-05-10 57 views
1

我想使用dart的postgresql驅動程序執行以下兩個插入操作。 下面的代碼工作!postgresql打開連接並執行多個命令

INSERT INTO posts(
      title, description, posted_at, last_edited, "user", 
      editor, up_votes, down_votes, flag, links_to) 
    VALUES ('test title', 'test description', now(), now(), 'dartUser', 'dartUser', 
      0, 0, 'healthy', 'http://google.com'); 


INSERT INTO atatched_tags(
      post_id, tag) 
    VALUES (currval('posts_post_id_seq'), 'testTag'); 

第二次插入只能在給予dart方法一個可選參數時完成。 我現在的代碼看起來像這樣。

addPost(Map post_values, [Map tag_values]){ 
    Connection conn; 
    connect(uri) 
    .then((_conn){ 
     conn = _conn; 
    }) 
    .then((_){ 
     conn.execute('''insert into posts(title, description, posted_at, last_edited, "user", editor, up_votes, down_votes, flag, links_to) 
            values(@title, @description, now(), now(), @user, @editor, @upVotes, @downVotes, @flag, @links_to)''', post_values) 
     .catchError((err){ 
     print('Execute error in addPost: $err'); 
    }) 
    .then((_){ 
     if(tag_values != null){ 
     _addTagToPost(conn, tag_values); 
     } 
    }) 
    .whenComplete(() => conn.close()); 
    }) 
    .catchError((err) => print('Error in addPost: $err')); 
    } 

    _addTagToPost(Connection conn, Map values) { 
    print('trying to add tag to attached tags'); 
    conn.execute("insert into atatched_tags values(currval('posts_post_id_seq'), @tag)", values) 
    .catchError((err){ 
     print('Execute error in addTagToPost: $err'); 
    }); 
    } 

我運行該方法如下。

dbUtil.addPost({'title': 'Sample title', 
    'description': 'This is a description for a sample post', 
    'user': 'dartUser', 'editor': 'dartUser', 'upVotes': 0, 
    'downVotes': 0, 'flag': 'healthy', 'links_to': 
    'http://google.com'}, {'tag':'testTag'}); 

dbUtil是上述兩種方法駐留的類的一個實例。

該代碼不會引發任何錯誤。但即使它寫入控制檯trying to add tag to attached tags,也不會執行第二次插入操作(表中未添加任何行)。第一個按預期工作。

任何幫助,非常感謝。

編輯:如果有人想在_addTagToPost函數中添加多個標籤,那麼這個代碼可能是有用的。 編輯2:下面的代碼是不正確我離開它,但檢查接受的答案中的意見。

Future _addTagToPost(Connection conn, List<Map> values) { 
    var completer = new Completer(); 
    values.forEach((value){ 
     conn.execute("insert into attached_tags values(currval('posts_post_id_seq'), @tag)", value) 
      .catchError((err){ 
      print('Execute error in addTagToPost: $err'); 
      }); 
    }); 
    return completer.future; 
    } 
+0

我更新了我的答案來完成。 –

回答

1

您需要添加一個return這裏

return _addTagToPost(conn, tag_values); 

Future _addTagToPost(Connection conn, Map values) { 
    print('trying to add tag to attached tags'); 
    return conn.execute(
     "insert into atatched_tags values(currval('posts_post_id_seq'), 
     @tag)", values) 
    .catchError((err){ 
    print('Execute error in addTagToPost: $err'); 
    }); 
} 

保持連接的異步操作。否則,連接在​​完成之前關閉,導致未完成此SQL語句。

更新到問題中的編輯。這也可以像

Future _addTagToPost(Connection conn, List<Map> values) { 
    return Future.wait(values.map((value){ 
    return conn.execute("insert into attached_tags values(currval('posts_post_id_seq'), @tag)", value) 
     .catchError((err){ 
      print('Execute error in addTagToPost: $err'); 
     }); 
    })); 
} 

Future _addTagToPost(Connection conn, List<Map> values) => 
    Future.wait(values.map((value) => conn 
     .execute(
      "insert into attached_tags values(currval('posts_post_id_seq'), @tag)", 
      value) 
     .catchError((err) => print('Execute error in addTagToPost: $err')))); 
+0

感謝您的更新。代碼看起來更好。還有速度收益嗎? – Lukasz

+0

相同的速度。但是現在我仔細看了一下你的代碼,發現它並沒有做它(或者我認爲它是)的目的。因爲不使用從'conn.execute()'返回的將來,所有命令完成時完成程序不會完成,但當所有命令都已入隊到Dart事件隊列(但尚未啓動)時,完成程序就已經完成。 'Future.wait'等待所有的期貨完成,然後完成未來的回報。 –

+1

你說得對。有趣的是,我的代碼仍然有效。看起來'execute'能夠在與數據庫的連接關閉之前完成任務。 – Lukasz

相關問題